Skip to content

test(Breadcrumbs): the hover-focus case hovers a row the menu's first frame did not focus - #8383

Closed
vjeux wants to merge 1 commit into
meta:mainfrom
vjeux:breadcrumbs-hover-focus-flake
Closed

vjeux wants to merge 1 commit into
meta:mainfrom
vjeux:breadcrumbs-hover-focus-flake

Conversation

@vjeux

@vjeux vjeux commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Review only this PR's change: the branch sits on main, so this diff is already its own.

Maintainer impact

What led to it: our merged #8221 added a Breadcrumbs test that turned out flaky in CI; another pull request's runs hit it about once in 15.

Why: the case "after a pointer open, a row the mouse rests on takes focus without :focus-visible" sometimes sees no focus call and fails a green pull request.

Intended invariant

The case guards that focus following the mouse onto a row after a pointer open carries focusVisible: false. That assertion is unchanged.

Change

The menu focuses its first row, Design, in the next animation frame. When that frame lands before the test's hover onto Design, Design already has focus, so hovering it moves nothing and the spy sees no call. The case now waits for that first focus, then hovers the next row, Engineering, so it passes in either order.

  • Retry the case. Hides the race instead of fixing it.
  • Fake timers for the frame. Works, but couples the test to how the menu schedules focus.
  • Wait, then hover another row (chosen). The smallest change that keeps the assertion; the cost is one extra wait.

Evidence

With the frame forced to land early, the old case fails every time with CI's message and the new case passes; it also passes with the frame forced late and over 200 natural repeats. Without the crumb's modality tracking, the new case fails, so it still guards the rule. Test only.

Scope

  • No intended public API, product behavior, visual direction, or policy change.
  • Product changes discovered during the work were removed or split.
  • Public text and artifacts contain no internal Meta context.

Testing

Run pnpm vitest run packages/core/src/Breadcrumbs: the suite passes, and the changed case passes whether the menu's first focus lands before or after the hover.

… frame did not focus

The case added with the menu-row hover focus fix (meta#8221) expected one focus({preventScroll: true, focusVisible: false}) call on the Design row after a pointer open, and sometimes saw none in CI. BreadcrumbItem opens its menu and focuses the first row, Design, in the next animation frame; when that frame landed before the test's pointerMove, Design already had focus, and focusMenuItemOnHover rightly moves nothing onto an element that has it. The case now waits for that frame's focus on Design, then hovers Engineering, so the hover moves focus in either order. It still guards the same rule: with the crumb's useInteractionModalityTracking() removed it fails. With requestAnimationFrame forced to fire before the hover, the previous case fails every time with the CI message (no call) and this one passes; it also passes with the frame forced late and over 200 repeats, idle and under load. Test only.
@vercel

vercel Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Oct 25, 2026 6:57am UTC

Request Review

@astracat-bot

astracat-bot Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Oct 25, 2026, 8:53 AM UTC

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 25, 2026

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommending approval. The hover-focus case now waits for the menu's first-row focus and then hovers Engineering, so it passes whether the animation frame lands before or after the hover, and its focusVisible: false assertion still fails if the Breadcrumbs menu stops activating modality tracking. No changes are needed.

[Automated review]

@github-actions

Copy link
Copy Markdown
Contributor

PR Analysis Report

📚 Storybook Preview

View Storybook for this PR

🧪 Sandbox Preview

View Sandbox for this PR

Component Size

Component Import before Import after Delta CSS before CSS after Delta
core/BreadcrumbItem 62.7KB 62.7KB 0B 10.8KB 10.8KB 0B
core/Breadcrumbs 22.3KB 22.3KB 0B 3.1KB 3.1KB 0B

Sizes are gzip. Import counts the JavaScript the import loads eagerly; CSS counts the package stylesheet rules referenced by the modules it can load from its own package, lazily loaded ones included.

Bundle Size Summary

Gzip figures measure each package's entry file, not the code an import pulls in.

Package Entry (ESM) Entry gzip before Entry gzip after Delta
@astryxdesign/core 4.9KB 1.2KB 1.2KB 0B
Package stylesheet Gzip before Gzip after Delta
@astryxdesign/core 33.7KB 33.7KB 0B

Accessibility Audit

Status: No accessibility violations detected.


Generated by PR Enrichment workflow | Storybook | Sandbox | View full report

@vjeux

vjeux commented Oct 28, 2026

Copy link
Copy Markdown
Contributor Author

Closing: #8824 fixed the same race the same way (it waits for the first row's focus, then hovers Engineering), so this one is no longer needed.

@vjeux vjeux closed this Oct 28, 2026

This branch was successfully deployed

1 active deployment
Preview — be8b7a7d Deployed Oct 25, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant