From 97a33b24b854cc31a4a2dff43578f506725e2c7d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 14:38:53 +0000 Subject: [PATCH] test: add unit tests for getFirstFocusableElement in focusTrap composable Add 16 unit tests covering getFirstFocusableElement from shell/composables/focusTrap.ts: - Returns document.body when no focusable elements exist (including default document parameter) - Identifies all focusable element types: button, anchor, input, textarea, select, details, tabindex >=0 - Excludes elements with tabindex="-1" - Skips disabled elements (button and input) - Returns document.body when all elements are disabled - Returns the first of multiple eligible elements - Returns first non-disabled element when leading elements are disabled Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- shell/composables/focusTrap.test.ts | 110 ++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 shell/composables/focusTrap.test.ts diff --git a/shell/composables/focusTrap.test.ts b/shell/composables/focusTrap.test.ts new file mode 100644 index 00000000000..b1820117edf --- /dev/null +++ b/shell/composables/focusTrap.test.ts @@ -0,0 +1,110 @@ +import { getFirstFocusableElement } from './focusTrap'; + +describe('getFirstFocusableElement', () => { + it('returns document.body when the container has no focusable elements', () => { + const container = document.createElement('div'); + + container.innerHTML = 'plain text

paragraph

'; + + expect(getFirstFocusableElement(container)).toStrictEqual(document.body); + }); + + it('returns document.body when no element argument is provided and document has no focusable elements', () => { + expect(getFirstFocusableElement()).toStrictEqual(document.body); + }); + + it.each([ + { + desc: 'button', + html: '', + }, + { + desc: 'anchor', + html: 'link', + }, + { + desc: 'input', + html: '', + }, + { + desc: 'textarea', + html: '', + }, + { + desc: 'select', + html: '', + }, + { + desc: 'details', + html: '
summary
', + }, + { + desc: 'element with tabindex="0"', + html: '
div
', + }, + { + desc: 'element with tabindex="1"', + html: '
div
', + }, + ])('returns the $desc element when it is the only focusable element', ({ html }) => { + const container = document.createElement('div'); + + container.innerHTML = html; + + const expected = container.firstElementChild; + + expect(getFirstFocusableElement(container)).toStrictEqual(expected); + }); + + it('skips a disabled button and returns the next non-disabled focusable element', () => { + const container = document.createElement('div'); + + container.innerHTML = ''; + const buttons = container.querySelectorAll('button'); + + expect(getFirstFocusableElement(container)).toStrictEqual(buttons[1]); + }); + + it('skips a disabled input and returns the next non-disabled focusable element', () => { + const container = document.createElement('div'); + + container.innerHTML = ''; + const button = container.querySelector('button'); + + expect(getFirstFocusableElement(container)).toStrictEqual(button); + }); + + it('returns document.body when every focusable element is disabled', () => { + const container = document.createElement('div'); + + container.innerHTML = ''; + + expect(getFirstFocusableElement(container)).toStrictEqual(document.body); + }); + + it('does not return an element with tabindex="-1"', () => { + const container = document.createElement('div'); + + container.innerHTML = '
not focusable
'; + + expect(getFirstFocusableElement(container)).toStrictEqual(document.body); + }); + + it('returns the first of multiple focusable elements', () => { + const container = document.createElement('div'); + + container.innerHTML = ''; + const [first] = container.querySelectorAll('button'); + + expect(getFirstFocusableElement(container)).toStrictEqual(first); + }); + + it('returns the first non-disabled element when leading elements are all disabled', () => { + const container = document.createElement('div'); + + container.innerHTML = ''; + const buttons = container.querySelectorAll('button'); + + expect(getFirstFocusableElement(container)).toStrictEqual(buttons[2]); + }); +});