Skip to content

test(ChatLayout): the hiding-affordance contract reads visibility as focus leaves - #9003

Merged
cixzhang merged 2 commits into
mainfrom
fix/chat-scroll-button-visibility-at-blur
Oct 30, 2026
Merged

cixzhang merged 2 commits into
mainfrom
fix/chat-scroll-button-visibility-at-blur

Conversation

@cixzhang

Copy link
Copy Markdown
Contributor

Maintainer impact

The release-time accessibility contracts can go red on a correct ChatLayout. In CI, "the hiding affordance releases focus before its fade finishes" failed: the scroll button's visibility was already hidden when the test looked. A red release check on a healthy commit holds the release.

Intended invariant

The contract is unchanged. When the scroll affordance hides, focus leaves it immediately (it becomes inert), while its visibility flips only after the fade. So focus has left while the button is still visible, and once the fade ends it is hidden.

Change

The test checked visibility: visible after polling for focus to leave. On a slow runner the fade can finish before that check runs, so it read hidden even though focus had left mid-fade.

The test now records the pill's computed visibility from a one-time blur listener on the affordance, the moment focus leaves it, and asserts that value was visible. Chromium fires blur when the focused element becomes inert. The final "hidden after the fade" assertion is unchanged. Test only: no product code and no Changeset.

Evidence

All runs were in Chromium against the Storybook built for the failing commit, with Playwright 1.61.1.

  • Failure before the change: 2/40 failures with the CPU saturated, with the same error and line as CI; 20/20 passes at normal load. A probe showed blur firing with visibility: visible, and the fade's transitionend arriving 200-300 ms later.
  • Success after the change: 40/40 at normal load. Under CPU saturation, 59/60; the one miss was the spec's shared manifest file being written by many parallel copies of this file, an artifact of the stress harness (CI runs a file on one worker), not this assertion.
  • Product/runtime behavior verified unchanged: no source change.

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

  • pnpm exec playwright test packages/core/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts --project chromium -g "releases focus before its fade" --repeat-each=40 --fully-parallel, at normal load and under CPU saturation, before and after.
  • prettier --check and eslint on the file are clean.

Credit: @cixzhang wrote this contract in #7738. This change only reads its "still visible" check at the moment focus leaves.

Posted by Cindy's agent on her behalf.

…focus leaves

The check that the pill is still visible ran after polling for focus to
leave; on a slow runner the fade had already finished. Visibility is now
recorded by a one-time blur listener on the affordance, the moment focus
leaves it. Same assertions. Test only.

Original contract by @cixzhang in #7738.
@vercel

vercel Bot commented Oct 30, 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 30, 2026 10:51am UTC

Request Review

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

astracat-bot Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Oct 30, 2026, 11:10 AM UTC

@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.

Recommended for approval: recording the pill's visibility in a one-time blur listener checks the contract at the moment focus leaves, so runner speed no longer decides the result. The check still fails if the scroll button stops releasing focus immediately when it hides, so it keeps guarding the regression it was written for. Nothing further is needed from you.

[Automated review]

@cixzhang cixzhang closed this Oct 30, 2026
@cixzhang cixzhang reopened this Oct 30, 2026
@cixzhang cixzhang closed this Oct 30, 2026
@cixzhang cixzhang reopened this Oct 30, 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.

Recommended for approval: recording the pill's visibility in a one-time blur listener checks the contract at the moment focus leaves, so runner speed no longer decides the result. The check still fails when the scroll button stops releasing focus as it hides, so it keeps guarding the regression it was written for, and merging main left the change itself untouched. Nothing further is needed from you.

[Automated review]

@cixzhang
cixzhang merged commit ac096a7 into main Oct 30, 2026
91 of 95 checks passed
@cixzhang
cixzhang deleted the fix/chat-scroll-button-visibility-at-blur branch October 30, 2026 11:35

This branch was successfully deployed

1 active deployment
Preview — b0a5151f Deployed Oct 30, 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