From b5d675d56c190a8e4cf3bed1173bdeffb01f3935 Mon Sep 17 00:00:00 2001 From: Colin Rotherham Date: Tue, 12 Dec 2023 15:43:33 +0000 Subject: [PATCH 1/3] Add `InitError` to throw for components already initialised --- .../src/govuk/errors/index.jsdom.test.mjs | 30 ++++++++++++++++++- .../govuk-frontend/src/govuk/errors/index.mjs | 16 ++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/govuk-frontend/src/govuk/errors/index.jsdom.test.mjs b/packages/govuk-frontend/src/govuk/errors/index.jsdom.test.mjs index 516bf1af91..7e85fbf80b 100644 --- a/packages/govuk-frontend/src/govuk/errors/index.jsdom.test.mjs +++ b/packages/govuk-frontend/src/govuk/errors/index.jsdom.test.mjs @@ -1,4 +1,9 @@ -import { ElementError, GOVUKFrontendError, SupportError } from './index.mjs' +import { + ElementError, + GOVUKFrontendError, + InitError, + SupportError +} from './index.mjs' describe('errors', () => { describe('GOVUKFrontendError', () => { @@ -47,6 +52,29 @@ describe('errors', () => { }) }) + describe('InitError', () => { + let $element + + beforeAll(() => { + $element = document.createElement('div') + $element.setAttribute('data-module', 'govuk-accordion') + }) + + it('is an instance of GOVUKFrontendError', () => { + expect(new InitError($element)).toBeInstanceOf(GOVUKFrontendError) + }) + + it('has its own name set', () => { + expect(new InitError($element).name).toBe('InitError') + }) + + it('provides feedback for modules already initialised', () => { + expect(new InitError($element).message).toBe( + 'Root element (`$module`) already initialised (`govuk-accordion`)' + ) + }) + }) + describe('ElementError', () => { it('is an instance of GOVUKFrontendError', () => { expect( diff --git a/packages/govuk-frontend/src/govuk/errors/index.mjs b/packages/govuk-frontend/src/govuk/errors/index.mjs index a4495ceb6e..2617a15d40 100644 --- a/packages/govuk-frontend/src/govuk/errors/index.mjs +++ b/packages/govuk-frontend/src/govuk/errors/index.mjs @@ -97,6 +97,22 @@ export class ElementError extends GOVUKFrontendError { } } +/** + * Indicates that a component is already initialised + */ +export class InitError extends GOVUKFrontendError { + name = 'InitError' + + /** + * @internal + * @param {Element} $module - HTML element already initialised + */ + constructor($module) { + const moduleName = $module.getAttribute('data-module') + super(`Root element (\`$module\`) already initialised (\`${moduleName}\`)`) + } +} + /** * Element error options * From f9d665f21003f44ebcb9f5a8453c5d37faa06720 Mon Sep 17 00:00:00 2001 From: Colin Rotherham Date: Mon, 8 Jan 2024 17:46:06 +0000 Subject: [PATCH 2/3] Throw `InitError` when components are already initialised --- .../govuk-frontend/src/govuk/common/index.mjs | 11 +++++++++ .../govuk/components/accordion/accordion.mjs | 2 +- .../src/govuk/components/button/button.mjs | 2 +- .../character-count/character-count.mjs | 2 +- .../components/checkboxes/checkboxes.mjs | 2 +- .../error-summary/error-summary.mjs | 2 +- .../exit-this-page/exit-this-page.mjs | 2 +- .../src/govuk/components/header/header.mjs | 2 +- .../notification-banner.mjs | 2 +- .../src/govuk/components/radios/radios.mjs | 2 +- .../govuk/components/skip-link/skip-link.mjs | 2 +- .../src/govuk/components/tabs/tabs.mjs | 2 +- .../src/govuk/govuk-frontend-component.mjs | 24 ++++++++++++++++--- 13 files changed, 43 insertions(+), 14 deletions(-) diff --git a/packages/govuk-frontend/src/govuk/common/index.mjs b/packages/govuk-frontend/src/govuk/common/index.mjs index c3f21d11e2..0842509834 100644 --- a/packages/govuk-frontend/src/govuk/common/index.mjs +++ b/packages/govuk-frontend/src/govuk/common/index.mjs @@ -200,6 +200,17 @@ export function setFocus($element, options = {}) { $element.focus() } +/** + * Checks if component is already initialised + * + * @internal + * @param {Element} $module - HTML element to be checked + * @returns {boolean} Whether component is already initialised + */ +export function isInitialised($module) { + return $module instanceof HTMLElement && 'moduleInit' in $module.dataset +} + /** * Checks if GOV.UK Frontend is supported on this page * diff --git a/packages/govuk-frontend/src/govuk/components/accordion/accordion.mjs b/packages/govuk-frontend/src/govuk/components/accordion/accordion.mjs index 479a048e39..dc48593a50 100644 --- a/packages/govuk-frontend/src/govuk/components/accordion/accordion.mjs +++ b/packages/govuk-frontend/src/govuk/components/accordion/accordion.mjs @@ -117,7 +117,7 @@ export class Accordion extends GOVUKFrontendComponent { * @param {AccordionConfig} [config] - Accordion config */ constructor($module, config = {}) { - super() + super($module) if (!($module instanceof HTMLElement)) { throw new ElementError({ diff --git a/packages/govuk-frontend/src/govuk/components/button/button.mjs b/packages/govuk-frontend/src/govuk/components/button/button.mjs index 23b3b589a4..420e745e51 100644 --- a/packages/govuk-frontend/src/govuk/components/button/button.mjs +++ b/packages/govuk-frontend/src/govuk/components/button/button.mjs @@ -31,7 +31,7 @@ export class Button extends GOVUKFrontendComponent { * @param {ButtonConfig} [config] - Button config */ constructor($module, config = {}) { - super() + super($module) if (!($module instanceof HTMLElement)) { throw new ElementError({ diff --git a/packages/govuk-frontend/src/govuk/components/character-count/character-count.mjs b/packages/govuk-frontend/src/govuk/components/character-count/character-count.mjs index e1d6905d81..b3ccf02c31 100644 --- a/packages/govuk-frontend/src/govuk/components/character-count/character-count.mjs +++ b/packages/govuk-frontend/src/govuk/components/character-count/character-count.mjs @@ -66,7 +66,7 @@ export class CharacterCount extends GOVUKFrontendComponent { * @param {CharacterCountConfig} [config] - Character count config */ constructor($module, config = {}) { - super() + super($module) if (!($module instanceof HTMLElement)) { throw new ElementError({ diff --git a/packages/govuk-frontend/src/govuk/components/checkboxes/checkboxes.mjs b/packages/govuk-frontend/src/govuk/components/checkboxes/checkboxes.mjs index 1b5ac2e88b..fab291c5b6 100644 --- a/packages/govuk-frontend/src/govuk/components/checkboxes/checkboxes.mjs +++ b/packages/govuk-frontend/src/govuk/components/checkboxes/checkboxes.mjs @@ -28,7 +28,7 @@ export class Checkboxes extends GOVUKFrontendComponent { * @param {Element | null} $module - HTML element to use for checkboxes */ constructor($module) { - super() + super($module) if (!($module instanceof HTMLElement)) { throw new ElementError({ diff --git a/packages/govuk-frontend/src/govuk/components/error-summary/error-summary.mjs b/packages/govuk-frontend/src/govuk/components/error-summary/error-summary.mjs index a541123312..624a83e75f 100644 --- a/packages/govuk-frontend/src/govuk/components/error-summary/error-summary.mjs +++ b/packages/govuk-frontend/src/govuk/components/error-summary/error-summary.mjs @@ -30,7 +30,7 @@ export class ErrorSummary extends GOVUKFrontendComponent { * @param {ErrorSummaryConfig} [config] - Error summary config */ constructor($module, config = {}) { - super() + super($module) if (!($module instanceof HTMLElement)) { throw new ElementError({ diff --git a/packages/govuk-frontend/src/govuk/components/exit-this-page/exit-this-page.mjs b/packages/govuk-frontend/src/govuk/components/exit-this-page/exit-this-page.mjs index 2d0d9c8e37..265448f8dc 100644 --- a/packages/govuk-frontend/src/govuk/components/exit-this-page/exit-this-page.mjs +++ b/packages/govuk-frontend/src/govuk/components/exit-this-page/exit-this-page.mjs @@ -79,7 +79,7 @@ export class ExitThisPage extends GOVUKFrontendComponent { * @param {ExitThisPageConfig} [config] - Exit This Page config */ constructor($module, config = {}) { - super() + super($module) if (!($module instanceof HTMLElement)) { throw new ElementError({ diff --git a/packages/govuk-frontend/src/govuk/components/header/header.mjs b/packages/govuk-frontend/src/govuk/components/header/header.mjs index 0e03a309b4..1fee86c8a1 100644 --- a/packages/govuk-frontend/src/govuk/components/header/header.mjs +++ b/packages/govuk-frontend/src/govuk/components/header/header.mjs @@ -43,7 +43,7 @@ export class Header extends GOVUKFrontendComponent { * @param {Element | null} $module - HTML element to use for header */ constructor($module) { - super() + super($module) if (!$module) { throw new ElementError({ diff --git a/packages/govuk-frontend/src/govuk/components/notification-banner/notification-banner.mjs b/packages/govuk-frontend/src/govuk/components/notification-banner/notification-banner.mjs index 95fc72f0f2..5d8a589a51 100644 --- a/packages/govuk-frontend/src/govuk/components/notification-banner/notification-banner.mjs +++ b/packages/govuk-frontend/src/govuk/components/notification-banner/notification-banner.mjs @@ -23,7 +23,7 @@ export class NotificationBanner extends GOVUKFrontendComponent { * @param {NotificationBannerConfig} [config] - Notification banner config */ constructor($module, config = {}) { - super() + super($module) if (!($module instanceof HTMLElement)) { throw new ElementError({ diff --git a/packages/govuk-frontend/src/govuk/components/radios/radios.mjs b/packages/govuk-frontend/src/govuk/components/radios/radios.mjs index 675d555754..336430f168 100644 --- a/packages/govuk-frontend/src/govuk/components/radios/radios.mjs +++ b/packages/govuk-frontend/src/govuk/components/radios/radios.mjs @@ -28,7 +28,7 @@ export class Radios extends GOVUKFrontendComponent { * @param {Element | null} $module - HTML element to use for radios */ constructor($module) { - super() + super($module) if (!($module instanceof HTMLElement)) { throw new ElementError({ diff --git a/packages/govuk-frontend/src/govuk/components/skip-link/skip-link.mjs b/packages/govuk-frontend/src/govuk/components/skip-link/skip-link.mjs index ea34d387be..2b6d276f57 100644 --- a/packages/govuk-frontend/src/govuk/components/skip-link/skip-link.mjs +++ b/packages/govuk-frontend/src/govuk/components/skip-link/skip-link.mjs @@ -18,7 +18,7 @@ export class SkipLink extends GOVUKFrontendComponent { * @throws {ElementError} when the linked element is missing or the wrong type */ constructor($module) { - super() + super($module) if (!($module instanceof HTMLAnchorElement)) { throw new ElementError({ diff --git a/packages/govuk-frontend/src/govuk/components/tabs/tabs.mjs b/packages/govuk-frontend/src/govuk/components/tabs/tabs.mjs index dce2df6bb8..0438c2b4c4 100644 --- a/packages/govuk-frontend/src/govuk/components/tabs/tabs.mjs +++ b/packages/govuk-frontend/src/govuk/components/tabs/tabs.mjs @@ -45,7 +45,7 @@ export class Tabs extends GOVUKFrontendComponent { * @param {Element | null} $module - HTML element to use for tabs */ constructor($module) { - super() + super($module) if (!$module) { throw new ElementError({ diff --git a/packages/govuk-frontend/src/govuk/govuk-frontend-component.mjs b/packages/govuk-frontend/src/govuk/govuk-frontend-component.mjs index 03154a2127..f95b86bb6d 100644 --- a/packages/govuk-frontend/src/govuk/govuk-frontend-component.mjs +++ b/packages/govuk-frontend/src/govuk/govuk-frontend-component.mjs @@ -1,5 +1,5 @@ -import { isSupported } from './common/index.mjs' -import { SupportError } from './errors/index.mjs' +import { isInitialised, isSupported } from './common/index.mjs' +import { InitError, SupportError } from './errors/index.mjs' /** * Base Component class @@ -14,9 +14,27 @@ export class GOVUKFrontendComponent { * Constructs a new component, validating that GOV.UK Frontend is supported * * @internal + * @param {Element | null} [$module] - HTML element to use for component */ - constructor() { + constructor($module) { this.checkSupport() + this.checkInitialised($module) + + // Mark component as initialised in HTML + $module?.setAttribute('data-module-init', 'true') + } + + /** + * Validates whether component is already initialised + * + * @private + * @param {Element | null} [$module] - HTML element to be checked + * @throws {InitError} when component is already initialised + */ + checkInitialised($module) { + if ($module && isInitialised($module)) { + throw new InitError($module) + } } /** From 5574dfaec5c7cbdabcba5d228e93e07b63e1cff1 Mon Sep 17 00:00:00 2001 From: Colin Rotherham Date: Tue, 12 Dec 2023 15:47:35 +0000 Subject: [PATCH 3/3] Add tests for initialising components twice --- .../accordion/accordion.puppeteer.test.js | 17 +++++++++++++++++ .../components/button/button.puppeteer.test.js | 17 +++++++++++++++++ .../character-count.puppeteer.test.js | 17 +++++++++++++++++ .../checkboxes/checkboxes.puppeteer.test.js | 17 +++++++++++++++++ .../error-summary.puppeteer.test.js | 17 +++++++++++++++++ .../exit-this-page.puppeteer.test.js | 17 +++++++++++++++++ .../components/header/header.puppeteer.test.js | 17 +++++++++++++++++ .../notification-banner.puppeteer.test.js | 17 +++++++++++++++++ .../components/radios/radios.puppeteer.test.js | 16 ++++++++++++++++ .../skip-link/skip-link.puppeteer.test.js | 17 +++++++++++++++++ .../components/tabs/tabs.puppeteer.test.js | 16 ++++++++++++++++ 11 files changed, 185 insertions(+) diff --git a/packages/govuk-frontend/src/govuk/components/accordion/accordion.puppeteer.test.js b/packages/govuk-frontend/src/govuk/components/accordion/accordion.puppeteer.test.js index 0dff09e761..82f575cf56 100644 --- a/packages/govuk-frontend/src/govuk/components/accordion/accordion.puppeteer.test.js +++ b/packages/govuk-frontend/src/govuk/components/accordion/accordion.puppeteer.test.js @@ -1,3 +1,5 @@ +/* eslint-disable no-new */ + const { goToExample, render, @@ -712,6 +714,21 @@ describe('/components/accordion', () => { }) }) + it('throws when initialised twice', async () => { + await expect( + render(page, 'accordion', examples.default, { + async afterInitialisation($module) { + const { Accordion } = await import('govuk-frontend') + new Accordion($module) + } + }) + ).rejects.toMatchObject({ + name: 'InitError', + message: + 'Root element (`$module`) already initialised (`govuk-accordion`)' + }) + }) + it('throws when $module is not set', async () => { await expect( render(page, 'accordion', examples.default, { diff --git a/packages/govuk-frontend/src/govuk/components/button/button.puppeteer.test.js b/packages/govuk-frontend/src/govuk/components/button/button.puppeteer.test.js index e6b3bf6590..dda57595a9 100644 --- a/packages/govuk-frontend/src/govuk/components/button/button.puppeteer.test.js +++ b/packages/govuk-frontend/src/govuk/components/button/button.puppeteer.test.js @@ -1,3 +1,5 @@ +/* eslint-disable no-new */ + const { render } = require('@govuk-frontend/helpers/puppeteer') const { getExamples } = require('@govuk-frontend/lib/components') @@ -329,6 +331,21 @@ describe('/components/button', () => { }) }) + it('throws when initialised twice', async () => { + await expect( + render(page, 'button', examples.default, { + async afterInitialisation($module) { + const { Button } = await import('govuk-frontend') + new Button($module) + } + }) + ).rejects.toMatchObject({ + name: 'InitError', + message: + 'Root element (`$module`) already initialised (`govuk-button`)' + }) + }) + it('throws when $module is not set', async () => { await expect( render(page, 'button', examples.default, { diff --git a/packages/govuk-frontend/src/govuk/components/character-count/character-count.puppeteer.test.js b/packages/govuk-frontend/src/govuk/components/character-count/character-count.puppeteer.test.js index 9cf41b60b3..a7cb85164c 100644 --- a/packages/govuk-frontend/src/govuk/components/character-count/character-count.puppeteer.test.js +++ b/packages/govuk-frontend/src/govuk/components/character-count/character-count.puppeteer.test.js @@ -1,3 +1,5 @@ +/* eslint-disable no-new */ + const { setTimeout } = require('timers/promises') const { render } = require('@govuk-frontend/helpers/puppeteer') @@ -814,6 +816,21 @@ describe('Character count', () => { }) }) + it('throws when initialised twice', async () => { + await expect( + render(page, 'character-count', examples.default, { + async afterInitialisation($module) { + const { CharacterCount } = await import('govuk-frontend') + new CharacterCount($module) + } + }) + ).rejects.toMatchObject({ + name: 'InitError', + message: + 'Root element (`$module`) already initialised (`govuk-character-count`)' + }) + }) + it('throws when $module is not set', async () => { await expect( render(page, 'character-count', examples.default, { diff --git a/packages/govuk-frontend/src/govuk/components/checkboxes/checkboxes.puppeteer.test.js b/packages/govuk-frontend/src/govuk/components/checkboxes/checkboxes.puppeteer.test.js index 1d046fc725..a87cb2fe05 100644 --- a/packages/govuk-frontend/src/govuk/components/checkboxes/checkboxes.puppeteer.test.js +++ b/packages/govuk-frontend/src/govuk/components/checkboxes/checkboxes.puppeteer.test.js @@ -1,3 +1,5 @@ +/* eslint-disable no-new */ + const { goToExample, getAttribute, @@ -363,6 +365,21 @@ describe('Checkboxes', () => { }) }) + it('throws when initialised twice', async () => { + await expect( + render(page, 'checkboxes', examples.default, { + async afterInitialisation($module) { + const { Checkboxes } = await import('govuk-frontend') + new Checkboxes($module) + } + }) + ).rejects.toMatchObject({ + name: 'InitError', + message: + 'Root element (`$module`) already initialised (`govuk-checkboxes`)' + }) + }) + it('throws when $module is not set', async () => { await expect( render(page, 'checkboxes', examples.default, { diff --git a/packages/govuk-frontend/src/govuk/components/error-summary/error-summary.puppeteer.test.js b/packages/govuk-frontend/src/govuk/components/error-summary/error-summary.puppeteer.test.js index c3788e8e86..285a0ecd17 100644 --- a/packages/govuk-frontend/src/govuk/components/error-summary/error-summary.puppeteer.test.js +++ b/packages/govuk-frontend/src/govuk/components/error-summary/error-summary.puppeteer.test.js @@ -1,3 +1,5 @@ +/* eslint-disable no-new */ + const { goToExample, render } = require('@govuk-frontend/helpers/puppeteer') const { getExamples } = require('@govuk-frontend/lib/components') @@ -236,6 +238,21 @@ describe('Error Summary', () => { }) }) + it('throws when initialised twice', async () => { + await expect( + render(page, 'error-summary', examples.default, { + async afterInitialisation($module) { + const { ErrorSummary } = await import('govuk-frontend') + new ErrorSummary($module) + } + }) + ).rejects.toMatchObject({ + name: 'InitError', + message: + 'Root element (`$module`) already initialised (`govuk-error-summary`)' + }) + }) + it('throws when $module is not set', async () => { await expect( render(page, 'error-summary', examples.default, { diff --git a/packages/govuk-frontend/src/govuk/components/exit-this-page/exit-this-page.puppeteer.test.js b/packages/govuk-frontend/src/govuk/components/exit-this-page/exit-this-page.puppeteer.test.js index cdd37cf7c8..452b206428 100644 --- a/packages/govuk-frontend/src/govuk/components/exit-this-page/exit-this-page.puppeteer.test.js +++ b/packages/govuk-frontend/src/govuk/components/exit-this-page/exit-this-page.puppeteer.test.js @@ -1,3 +1,5 @@ +/* eslint-disable no-new */ + const { setTimeout } = require('timers/promises') const { goToExample, render } = require('@govuk-frontend/helpers/puppeteer') @@ -231,6 +233,21 @@ describe('/components/exit-this-page', () => { }) }) + it('throws when initialised twice', async () => { + await expect( + render(page, 'exit-this-page', examples.default, { + async afterInitialisation($module) { + const { ExitThisPage } = await import('govuk-frontend') + new ExitThisPage($module) + } + }) + ).rejects.toMatchObject({ + name: 'InitError', + message: + 'Root element (`$module`) already initialised (`govuk-exit-this-page`)' + }) + }) + it('throws when $module is not set', async () => { await expect( render(page, 'exit-this-page', examples.default, { diff --git a/packages/govuk-frontend/src/govuk/components/header/header.puppeteer.test.js b/packages/govuk-frontend/src/govuk/components/header/header.puppeteer.test.js index d4f81f1f81..ec37001e69 100644 --- a/packages/govuk-frontend/src/govuk/components/header/header.puppeteer.test.js +++ b/packages/govuk-frontend/src/govuk/components/header/header.puppeteer.test.js @@ -1,3 +1,5 @@ +/* eslint-disable no-new */ + const { render } = require('@govuk-frontend/helpers/puppeteer') const { getExamples } = require('@govuk-frontend/lib/components') const { KnownDevices } = require('puppeteer') @@ -179,6 +181,21 @@ describe('Header navigation', () => { }) }) + it('throws when initialised twice', async () => { + await expect( + render(page, 'header', examples.default, { + async afterInitialisation($module) { + const { Header } = await import('govuk-frontend') + new Header($module) + } + }) + ).rejects.toMatchObject({ + name: 'InitError', + message: + 'Root element (`$module`) already initialised (`govuk-header`)' + }) + }) + it('throws when $module is not set', async () => { await expect( render(page, 'header', examples.default, { diff --git a/packages/govuk-frontend/src/govuk/components/notification-banner/notification-banner.puppeteer.test.js b/packages/govuk-frontend/src/govuk/components/notification-banner/notification-banner.puppeteer.test.js index 0137d49c76..8b1c0a44cf 100644 --- a/packages/govuk-frontend/src/govuk/components/notification-banner/notification-banner.puppeteer.test.js +++ b/packages/govuk-frontend/src/govuk/components/notification-banner/notification-banner.puppeteer.test.js @@ -1,3 +1,5 @@ +/* eslint-disable no-new */ + const { render } = require('@govuk-frontend/helpers/puppeteer') const { getExamples } = require('@govuk-frontend/lib/components') @@ -236,6 +238,21 @@ describe('Notification banner', () => { }) }) + it('throws when initialised twice', async () => { + await expect( + render(page, 'notification-banner', examples.default, { + async afterInitialisation($module) { + const { NotificationBanner } = await import('govuk-frontend') + new NotificationBanner($module) + } + }) + ).rejects.toMatchObject({ + name: 'InitError', + message: + 'Root element (`$module`) already initialised (`govuk-notification-banner`)' + }) + }) + it('throws when $module is not set', async () => { await expect( render(page, 'notification-banner', examples.default, { diff --git a/packages/govuk-frontend/src/govuk/components/radios/radios.puppeteer.test.js b/packages/govuk-frontend/src/govuk/components/radios/radios.puppeteer.test.js index 37561d3372..0eda543b15 100644 --- a/packages/govuk-frontend/src/govuk/components/radios/radios.puppeteer.test.js +++ b/packages/govuk-frontend/src/govuk/components/radios/radios.puppeteer.test.js @@ -1,3 +1,5 @@ +/* eslint-disable no-new */ + const { goToExample, getProperty, @@ -316,6 +318,20 @@ describe('Radios', () => { }) }) + it('throws when initialised twice', async () => { + await expect( + render(page, 'radios', examples.default, { + async afterInitialisation($module) { + const { Radios } = await import('govuk-frontend') + new Radios($module) + } + }) + ).rejects.toMatchObject({ + name: 'InitError', + message: 'Root element (`$module`) already initialised (`govuk-radios`)' + }) + }) + it('throws when $module is not set', async () => { await expect( render(page, 'radios', examples.default, { 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 cd3b7f8cc1..6b0f614f09 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 @@ -1,3 +1,5 @@ +/* eslint-disable no-new */ + const { render } = require('@govuk-frontend/helpers/puppeteer') const { getExamples } = require('@govuk-frontend/lib/components') @@ -119,6 +121,21 @@ describe('Skip Link', () => { }) }) + it('throws when initialised twice', async () => { + await expect( + render(page, 'skip-link', examples.default, { + async afterInitialisation($module) { + const { SkipLink } = await import('govuk-frontend') + new SkipLink($module) + } + }) + ).rejects.toMatchObject({ + name: 'InitError', + message: + 'Root element (`$module`) already initialised (`govuk-skip-link`)' + }) + }) + it('throws when $module is not set', async () => { await expect( render(page, 'skip-link', examples.default, { diff --git a/packages/govuk-frontend/src/govuk/components/tabs/tabs.puppeteer.test.js b/packages/govuk-frontend/src/govuk/components/tabs/tabs.puppeteer.test.js index 99326cf177..aa6682edfa 100644 --- a/packages/govuk-frontend/src/govuk/components/tabs/tabs.puppeteer.test.js +++ b/packages/govuk-frontend/src/govuk/components/tabs/tabs.puppeteer.test.js @@ -1,3 +1,5 @@ +/* eslint-disable no-new */ + const { render } = require('@govuk-frontend/helpers/puppeteer') const { getExamples } = require('@govuk-frontend/lib/components') const { KnownDevices } = require('puppeteer') @@ -269,6 +271,20 @@ describe('/components/tabs', () => { }) }) + it('throws when initialised twice', async () => { + await expect( + render(page, 'tabs', examples.default, { + async afterInitialisation($module) { + const { Tabs } = await import('govuk-frontend') + new Tabs($module) + } + }) + ).rejects.toMatchObject({ + name: 'InitError', + message: 'Root element (`$module`) already initialised (`govuk-tabs`)' + }) + }) + it('throws when $module is not set', async () => { await expect( render(page, 'tabs', examples.default, {