Skip to content

fix: mock useId to fix ESC test in nested portal scenarios#502

Merged
zombieJ merged 1 commit intoreact-component:masterfrom
aojunhao123:fix/ci-failed
Mar 17, 2026
Merged

fix: mock useId to fix ESC test in nested portal scenarios#502
zombieJ merged 1 commit intoreact-component:masterfrom
aojunhao123:fix/ci-failed

Conversation

@aojunhao123
Copy link
Contributor

@aojunhao123 aojunhao123 commented Mar 17, 2026

useId 为了确保测试环境的 snapshot 稳定,返回值写死为 'test-id',导致了这个 test case 挂掉,reset 回去就行

那么为什么我在 #494 里写下这个 case 的时候没出现这个问题呢?那就要说到这个 pr 了:
在这个 pr 之前,Portal 处理 keydown 时是每个 Portal 实例各自注册独立的 listener,即使多个 Portal 的 useId() 返回了相同的 'test-id',每个 handler 仍然会独立触发,Preview 的 onEsc 依然能收到 Escape 事件。

而这个 pr 将实现重构为单一全局 listener + 内部 stack 遍历的方式,stack 的入栈逻辑通过 id 做去重。当 Dialog 的 Portal 先入栈(id='test-id'),Preview 的 Portal 再尝试入栈时发现已存在相同 id 的条目,就直接跳过了。导致 Escape 事件永远只通知到 Dialog,Preview 的 onClose 从未被调用。

顺带一提,这个问题其实不复杂但是涉及上下文比较多,仅把报错信息提供给 AI 的话目前它还是很难推理出完整上下文来给出一个根本性的解法的

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on improving the stability of existing tests by addressing a specific interaction issue related to the useId hook in nested portal environments. By mocking useId to use React's native implementation, the PR ensures that tests involving ESC key events in complex UI structures behave as expected, preventing false negatives.

Highlights

  • Test Stability: Implemented a mock for the useId hook within tests/preview.test.tsx to resolve issues with ESC key functionality in nested portal test scenarios.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • tests/preview.test.tsx
    • Removed the useState import as it was no longer needed.
    • Added a jest.mock call for @rc-component/util/lib/hooks/useId to use React.useId for consistent behavior in tests.
Activity
  • No specific activity (comments, reviews, progress) has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@vercel
Copy link

vercel bot commented Mar 17, 2026

@aojunhao123 is attempting to deploy a commit to the React Component Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Mar 17, 2026

概述

修改测试文件以优化模块导入和添加useId钩子的模拟实现,确保在测试环境中实现一致的ID生成。单个文件受影响,改动精准专注。

变更

文件群组 / 文件 变更摘要
测试工具配置
tests/preview.test.tsx
调整React导入(移除useState),添加useId钩子的模拟实现,并在Image模块导入前初始化,以支持测试中的ID生成。

代码审查工作量评估

🎯 2 (简单) | ⏱️ ~8 分钟

建议审查者

  • thinkasany

诗歌

🐰 兔兔奔跑在测试的田野,
useId来临如春风化雨,
Mock的魔法让ID相通,
导入精简,逻辑更清,
小小改动,测试闪闪亮!✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR标题准确描述了主要变更——在嵌套门户场景中通过模拟useId来修复ESC测试问题。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request aims to fix a test for nested portals by mocking useId. The change involves removing an unused useState import and adding a mock for @rc-component/util/lib/hooks/useId. My review includes a suggestion to make the mock more robust and align with Jest's documentation for mocking ES modules with default exports.

@codecov
Copy link

codecov bot commented Mar 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.41%. Comparing base (b973819) to head (7cf68ae).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #502   +/-   ##
=======================================
  Coverage   99.41%   99.41%           
=======================================
  Files          17       17           
  Lines         511      511           
  Branches      153      153           
=======================================
  Hits          508      508           
  Misses          3        3           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/preview.test.tsx (1)

26-29: Mock 实现正确,已修复嵌套 Portal 场景下的 ESC 测试问题。

使用 React 18 原生的 useId 来 mock @rc-component/util/lib/hooks/useId,确保测试中 ID 生成的一致性。这个方案有效地解决了嵌套 Portal 场景下 ESC 键处理的问题。

小建议:变量名 origin 可以改为更具描述性的名称,如 ReactactualReact,提升代码可读性。

♻️ 可选的命名改进
 jest.mock('@rc-component/util/lib/hooks/useId', () => {
-  const origin = jest.requireActual('react');
-  return origin.useId;
+  const React = jest.requireActual('react');
+  return React.useId;
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/preview.test.tsx` around lines 26 - 29, The mock for
'@rc-component/util/lib/hooks/useId' uses a non-descriptive variable name
"origin"; rename it to a clearer identifier (e.g., React or actualReact) inside
the jest.mock callback so the line that assigns const origin =
jest.requireActual('react') becomes const React = jest.requireActual('react')
(or const actualReact = ...), and then return React.useId (or actualReact.useId)
to improve readability while keeping the existing mock behavior in the
jest.mock(...) block that targets useId.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/preview.test.tsx`:
- Around line 26-29: The mock for '@rc-component/util/lib/hooks/useId' uses a
non-descriptive variable name "origin"; rename it to a clearer identifier (e.g.,
React or actualReact) inside the jest.mock callback so the line that assigns
const origin = jest.requireActual('react') becomes const React =
jest.requireActual('react') (or const actualReact = ...), and then return
React.useId (or actualReact.useId) to improve readability while keeping the
existing mock behavior in the jest.mock(...) block that targets useId.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 21ebe1c9-25ee-4b65-a945-1aadb73ad141

📥 Commits

Reviewing files that changed from the base of the PR and between dfc83c5 and 7cf68ae.

📒 Files selected for processing (1)
  • tests/preview.test.tsx

@zombieJ zombieJ merged commit 718a756 into react-component:master Mar 17, 2026
7 of 8 checks passed
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