Skip to content

Flyout Template Accessibility Tests - #290716

Draft
tsullivan wants to merge 4 commits into
elastic:mainfrom
tsullivan:flyout/accessibility-fixes
Draft

Flyout Template Accessibility Tests #290716
tsullivan wants to merge 4 commits into
elastic:mainfrom
tsullivan:flyout/accessibility-fixes

Conversation

@tsullivan

@tsullivan tsullivan commented Sep 12, 2026

Copy link
Copy Markdown
Member

Summary

Automated functional UI tests for https://github.com/elastic/kibana-team/issues/3165

Tests Added

Suite Description
full_surface_a11y.spec.ts Runs axe-core accessibility scans on the full component and service widget flyouts. Validates that sections act as named regions, accordions correctly expose ARIA states, badges overflow into accessible popovers, and tabs adhere to the roving tabindex pattern.
header_collapse_a11y.spec.ts Tests the collapse-on-scroll functionality via actual keyboard (PageDown, Home) and mouse wheel interactions. Ensures the header's collapsible region is removed from the tab order, focus is managed appropriately, aria-hidden/inert states agree, and the footer is reachable at high zoom levels (WCAG 1.4.10 reflow).
dialog_focus_a11y.spec.ts Evaluates that opening a flyout traps focus within the dialog, and closing a flyout (via footer, header, escape key, or for child flyouts) reliably returns focus back to its opening trigger. Tests run with both ownFocus true and false.
resizable_a11y.spec.ts Confirms the resize handle is reachable via keyboard (Tab), resizable with arrow keys, has a descriptive accessible name, and strictly honors the configured minimum width boundary (minWidth).

Bugs Fixed

Bug Description Fix
Stranded focus during collapse (F1) Collapsing the header hid focusable elements, throwing focus out of the dialog onto the <body>. Before collapsing, the code now checks if focus is inside the collapsible region and deliberately moves it to the scrollable body (scroller.focus()).
Mid-animation focusability (F2) During the collapse animation, visibility: hidden is delayed, leaving elements aria-hidden="true" but still focusable. Added inert="" to the wrapper when collapsed so the accessibility tree and tab order update instantly and in agreement.
Swallowed wheel events (F6) At high zoom/small viewports, EUI wraps the flyout in an outer scroller. A rigid preventDefault on wheel events in the header prevented this outer container from scrolling, blocking access to the footer (a WCAG 1.4.10 reflow failure). Added an isAtScrollEdge guard so preventDefault is bypassed when the internal scroller is already maxed out, allowing the browser to chain the scroll to the parent.

TODOs Arisen

  • Header Title Tooltip: The title tooltip completely disappears on collapse because renderTitleIcon is omitted from the compact title. This removes a focusable element and the tooltip's contents. Needs design review on whether to squeeze the icon into the compact row.
  • EUI Resize Handle Semantics: EuiFlyoutResizeButton acts like a slider but lacks slider value semantics (role="separator", aria-valuenow). Since the template can't pass arbitrary props to it, this requires an upstream fix in EUI.
  • InfoBlock and MetaBlock Pairing: Currently, these components pair titles and values visually but lack semantic <dl> list structures or programmatic ARIA associations. Upgrading this requires changing DOM structure in @kbn/flyout-info-blocks and @kbn/flyout-meta-blocks.
  • EUI Focus Return: Remove the returnFocusToTrigger timeout hack in the examples once EUI adds internal support for returning focus to the trigger element on close (tracking elastic/eui#9365).

Checklist

Check the PR satisfies following conditions.

Reviewers should verify this PR satisfies this list as well.

  • Any text added follows EUI's writing guidelines, uses sentence case text and includes i18n support
  • Documentation was added for features that require explanation or tutorials
  • Unit or functional tests were updated or added to match the most common scenarios
  • If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the docker list
  • This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The release_note:breaking label should be applied in these situations.
  • Flaky Test Runner was used on any tests changed
  • The PR description includes the appropriate Release Notes section, and the correct release_note:* label is applied per the guidelines
  • Review the backport guidelines and apply applicable backport:* labels.

Identify risks

Does this PR introduce any risks? For example, consider risks like hard to test bugs, performance regression, potential of data loss.

Describe the risk, its severity, and mitigation for each identified risk. Invite stakeholders and evaluate how to proceed before merging.

@infra-vault-gh-plugin-prod

infra-vault-gh-plugin-prod Bot commented Sep 12, 2026

Copy link
Copy Markdown
🤖 Jobs for this PR can be triggered through checkboxes. 🚧

ℹ️ To trigger the CI, please tick the checkbox below 👇

  • Click to trigger kibana-pull-request for this PR!
  • Click to trigger kibana-deploy-project-from-pr for this PR!
  • Click to trigger kibana-deploy-cloud-from-pr for this PR!
  • Click to trigger kibana-entity-store-performance-from-pr for this PR!
  • Click to trigger kibana-storybooks-from-pr for this PR!

@tsullivan
tsullivan force-pushed the flyout/accessibility-fixes branch from 5966481 to f37a721 Compare September 12, 2026 17:27
@kibanamachine

Copy link
Copy Markdown
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
shared-packages 1262 1263 +1

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
shared-core 282.6KB 283.8KB +1.2KB
shared-packages 4.6MB 4.6MB +196.0B
total +1.4KB
Unknown metric groups

ESLint disabled line counts

id before after diff
@kbn/core-overlays-browser-internal 0 1 +1
@kbn/flyout-template 5 6 +1
total +2

shared async chunks total size

id before after diff
all 15.2MB 15.2MB +21.7KB

shared chunks total size

id before after diff
all 7.0MB 7.0MB +37.0B

Total ESLint disabled count

id before after diff
@kbn/core-overlays-browser-internal 2 3 +1
@kbn/flyout-template 5 6 +1
total +2

total optimizer output size

id before after diff
all 64.0MB 64.0MB +23.1KB

History

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants