Skip to content

Commit

Permalink
fixup! Improve hook for running code before initialisation in `render…
Browse files Browse the repository at this point in the history
…AndInitialise`
  • Loading branch information
romaricpascal committed Aug 1, 2023
1 parent f09d2d9 commit 9fd3f16
Showing 1 changed file with 23 additions and 15 deletions.
38 changes: 23 additions & 15 deletions shared/helpers/puppeteer.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,12 @@ async function axe (page, overrides = {}) {
* Render and initialise a component within test boilerplate HTML
*
* Renders a component's Nunjucks macro with the given params, injects it into
* the test boilerplate page, then either:
* the test boilerplate page, and instantiates the component class, passing the
* provided JavaScript configuration.
*
* - instantiates the component class, passing the provided JavaScript
* configuration
* - runs the passed initialiser function inside the browser
* (which lets you instantiate it a different way, like using `initAll`,
* or run arbitrary code)
* It runs an the `beforeInitialisation` function before initialising the
* components, allowing to tweak the state of the page before the component gets
* instantiated.
*
* @param {import('puppeteer').Page} page - Puppeteer page object
* @param {string} componentName - The kebab-cased name of the component
Expand All @@ -91,19 +90,28 @@ async function renderAndInitialise (page, componentName, options) {
slot.innerHTML = htmlForSlot
}, html)

const componentRootHandle = await page.$('[data-module]')

// Call `beforeInitialisation` in a separate `$eval` call
// as running it inside the body of the next `evaluate`
// didn't provide a reliable execution
if (options.beforeInitialisation) {
await componentRootHandle.evaluate(options.beforeInitialisation)
await page.$eval('[data-module]', options.beforeInitialisation)
}

// Run a script to init the JavaScript component
// Puppeteer returns very little information on errors thrown during `evaluate`,
// only a `name` that maps to the error class (and not its `name` property,
// which means we get a mangled value).
// As a workaround, we can gather and `return` the values we need from inside the browser,
// and throw them when back in Jest (to keep them triggering a Promise rejection)
const error = await componentRootHandle.evaluate(async ($module, exportName, options) => {
//
// Use `evaluate` to ensure we run `document.querySelector` inside the
// browser, like users would, rather than rely on Puppeteer looking for the
// element which would cause an error in Jest-land rather than within the
// browser if the element is missingß
//
// Puppeteer returns very little information on errors thrown during
// `evaluate`, only a `name` that maps to the error class (and not its `name`
// property, which means we get a mangled value). As a workaround, we can
// gather and `return` the values we need from inside the browser, and throw
// them when back in Jest (to keep them triggering a Promise rejection)
const error = await page.evaluate(async (exportName, options) => {
const $module = document.querySelector('[data-module]')

const namespace = await import('govuk-frontend')

try {
Expand Down

0 comments on commit 9fd3f16

Please sign in to comment.