尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

React Spectrum 测试工具包 @react-spectrum/test-utils 解析:ARIA 模式测试器与桌面/移动端变体模拟

React Spectrum 测试工具包 @react-spectrum/test-utils 解析:ARIA 模式测试器与桌面/移动端变体模拟 React Spectrum 测试工具包 react-spectrum/test-utils 解析ARIA 模式测试器与桌面/移动端变体模拟【免费下载链接】react-spectrumA collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.项目地址: https://gitcode.com/GitHub_Trending/re/react-spectrumreact-spectrum/test-utils是 React Spectrum 仓库中面向组件单元测试的官方测试工具包它把react-aria/test-utils提供的 ARIA 模式测试器Pattern Tester整体再导出并额外提供simulateMobile/simulateDesktop两个 Jest 环境下切换组件移动端/桌面端变体的助手。读完本文你将掌握如何用UsercreateTester以声明式、类型安全的方式查询与操作 ComboBox、Table、Dialog 等 ARIA 组件以及如何通过 mockwindow.screen.width来验证响应式渲染分支。包定位与再导出结构该包的核心是聚合 补充。从源码结构看入口文件 packages/react-spectrum/test-utils/src/index.ts 只有两行有效导出export * from react-aria/test-utils; export * from ./testSetup;export * from react-aria/test-utils把 ARIA 模式测试器体系User、triggerLongPress、installMouseEvent、installPointerEvent、pointerMap等完整转给使用者因此两个包的 API 可以互换使用export * from ./testSetup导出本包自有的simulateMobile与simulateDesktop。package.json 明确了依赖边界dependencies中只有react-aria/test-utils1.0.0-rc.1与swc/helperspeerDependencies要求testing-library/dom ^10.0.0、testing-library/user-event ^14.0.0、jest ^29.5.0 || ^30.0.0、react ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1。README 特别强调该库基于testing-library/dom10与testing-library/user-event14这些测试工具需要 React 18 才能正常工作使用时需确保项目满足该前提。安装与标准 Setup安装方式README 原文npm install react-spectrum/test-utils --devREADME 给出的标准 Setup 是在测试文件顶部初始化一个User对象在测试用例中通过它创建 ARIA 模式测试器。测试器提供查询特定子组件与模拟常见交互的方法// YourTest.test.ts import {screen} from testing-library/react; import {User} from react-spectrum/test-utils; // Provide whatever method of advancing timers you use in your test, this example assumes Jest with fake timers. // interactionType specifies what mode of interaction should be simulated by the tester // advanceTimer is used by the tester to advance the timers in the tests for specific interactions (e.g. long press) let testUtilUser new User({interactionType: mouse, advanceTimer: jest.advanceTimersByTime}); // ... it(my test case, async function () { // Render your test component/app render(); // Initialize the table tester via providing the Table pattern name and the root element of said table let table testUtilUser.createTester(Table, {root: screen.getByTestId(test_table)}); // ... });仓库内的真实测试与这一模式完全一致。例如 packages/react-spectrum/s2/test/Combobox.test.tsx 在describe顶部创建let testUtilUser new User();各用例中再testUtilUser.createTester(ComboBox, {root: tree.container})随后调用comboboxTester.open()、comboboxTester.getOptions()等方法完成断言。User API两个构造参数如何生效README 中给出的UserAPI 签名class User { constructor(opts?: { interactionType?: mouse | keyboard | touch, advanceTimer?: (time?: number) void | Promiseunknown }); createTester(patternName, opts): PatternTester; }interactionType— 从该User创建的 tester 使用的默认交互模式单个 tester 可通过setInteractionType或按方法选项覆盖。advanceTimer— tester 用来推进长按等交互计时器的函数使用 fake timers 时传jest.advanceTimersByTime或测试框架等价物。createTester(patternName, opts)— 返回给定 ARIA 模式的 testeropts.root为被测组件的根元素。结合底层实现 packages/react-aria/test-utils/src/user.ts 可以看到这两项参数的具体落地User构造函数内部通过userEvent.setup({delay: null, pointerMap})创建一个testing-library/user-event实例。pointerMap是 React Aria 自己维护的指针键位映射delay: null保证交互事件之间无人为延迟测试确定且快速interactionType未显式指定时默认为mouse类型定义见 packages/react-aria/test-utils/src/types.ts 的UserOptsJSDoc 明确标注default mouseadvanceTimer未提供时回退到真实的setTimeout实现let defaultAdvanceTimer (waitTime: number | undefined) new Promise(resolve setTimeout(resolve, waitTime));这意味着启用 Jest fake timers 的测试必须显式传入advanceTimer: jest.advanceTimersByTime否则长按等待会挂起不使用 fake timers 的测试可以完全省略该参数。createTester的实现展示了精确的类型推导源码维护一张keyToUtil模式名到 Tester 类的映射表并用条件类型TesterT/TesterOptsT让模式名、返回的 tester 类型与opts选项类型一一对应——写错模式名或漏传必填的root会在编译期报错。createTester还会把User的interactionType、advanceTimer与内部user实例注入每个 tester 的构造函数调用方传入的opts参与展开允许按需覆盖。支持的 ARIA 模式PatternsREADME 列出createTester支持的 ARIA 模式并指向 React Spectrum 文档站中各组件的 testing 页面查看每个 tester 的用例示例CheckboxGroupComboBoxDialogListViewMenuPickerRadioGroupTableViewTabsTreeView从源码结构看packages/react-aria/test-utils/src/user.ts 中keyToUtil实际注册的 tester 键为CheckboxGroup、ComboBox、Dialog、GridList、ListBox、Menu、RadioGroup、Select、Table、Tabs、Tree——即 README 中的 RSP 组件名对应底层 ARIA 模式例如 TableView 对应TableListView 对应GridList/ListBox一类的网格/列表模式。每个模式的额外选项BaseTesterOpts要求必填root: HTMLElementtester 的基础元素如表格本身、菜单触发按钮等可选direction?: ltr | rtl默认ltr通常受 locale 影响。各模式在 packages/react-aria/test-utils/src/types.ts 中还有差异化选项例如ComboBoxTesterOpts可传triggercombobox 触发按钮若只传包裹元素的root如 RSP ComboBox 的 ref 所在容器tester 会自动在root内查找 combobox 元素DialogTesterOpts可传overlayType?: modal | popover用于告知 tester 以何种 overlay 类型定位 dialogGridListTesterOpts/ListBoxTesterOptslayout?: stack | grid默认stackMenuTesterOptsisSubmenu?: boolean以及子菜单场景下的rootMenu?: HTMLElement。行/网格类交互还有通用选项BaseGridRowInteractionOptsrow可以是行索引、文本或节点interactionType可按方法覆盖以及ToggleGridRowOpts中的needsLongPress、checkboxSelection默认 true为 false 时改用按压选择行、selectionBehavior?: toggle | replace默认toggle用于在selectionBehavior: replace的网格中模拟带修饰键的多行选择操作。Tester 提供的查询与交互方法以源码为证ComboBoxTesterpackages/react-aria/test-utils/src/combobox.ts交互类open()、toggleOptionSelection({indexOrText})、close()、setInteractionType(type)查询类getCombobox()、getTrigger()、getListbox()未打开时可能为null、getSections()、getOptions({element?})、getFocusedOption()、findOption({indexOrText})。仓库内 packages/react-spectrum/s2/test/Combobox.test.tsx 中的用例展示了典型断言流程渲染空选项的ComboBox后先断言comboboxTester.getListbox()为 falsy再await comboboxTester.open()最后断言唯一选项文本为No results且 listbox 内存在loadMoreSentinel。TableTesterpackages/react-aria/test-utils/src/table.ts交互类toggleRowSelection、toggleRowExpansion、toggleSort、triggerColumnHeaderAction、triggerRowAction、toggleSelectAll均可按方法指定interactionType查询类getTable()、getRows({element?})、getSelectedRows()、getFooterRows()、getRowHeaders()、getCells({element?})、getColumns()、getRowGroups()、findRow({indexOrText})、findCell({text})。react-spectrum/s2的 TableView 测试 中实际调用了tableTester.getRows()、getCells()、getColumns()、getRowGroups()、triggerColumnHeaderAction()等方法印证了这套 API 在组件测试中的真实用法。长按与按压模拟的底层工具utils.ts 还暴露了triggerLongPress与pressElement等基础工具triggerLongPress({element, advanceTimer, pointerOpts})按pointerTypemouse/touch依次派发pointerdown、兼容事件mousedown/touchstart、advanceTimer(500)DEFAULT_LONG_PRESS_TIME 500ms、pointerup与click从而在 fake timers 下也能确定性触发长按逻辑pressElement(user, element, interactionType)则统一了三种模态的按压——mouse 走user.pointer带[MouseLeft]键位keyboard 先 focus 再按[Space]touch 走[TouchA]。simulateMobile / simulateDesktop桌面/移动端变体切换README 指出除再导出外本包提供simulateMobile和simulateDesktop两个助手用于在测试中切换组件的移动端/桌面端变体仅限 Jest。实现位于 packages/react-spectrum/test-utils/src/testSetup.ts/** Mocks screen width to simulate mobile experience, useful for testing Tray rendering. */ export function simulateMobile(width: number 700): void { jest .spyOn(window.screen, width, get) .mockImplementation(() Math.min(Math.max(width, 0), 700)); } /** Mocks screen width to simulate standard desktop experience. */ export function simulateDesktop(width: number 701): void { jest.spyOn(window.screen, width, get).mockImplementation(() Math.max(width, 701)); }要点两者都通过jest.spyOn(window.screen, width, get)替换window.screen.width的 getter这正是Jest only的原因——依赖jest.spyOn非 Jest 框架无法直接使用simulateMobile默认 700px传入值会被钳制在[0, 700]simulateDesktop默认 701px传入值会被钳制为 701。也就是说700 / 701 是组件区分移动与桌面渲染的边界源码注释提到它对测试 Tray 等依赖屏幕宽度的渲染分支尤其有用由于是 spy测试结束后按常规jest.restoreAllMocks()或在afterEach中恢复即可。仓库内的实际用例可作参照packages/adobe/react-spectrum/test/table/TableSizing.test.tsx 在多个桌面宽度断言场景中调用simulateDesktop()经由react-spectrum/test-utils-internal导入同一套源码packages/react-aria/test/aria-modal-polyfill/index.test.tsx 则使用simulateMobile()验证窄屏下的模态渲染行为。小结react-spectrum/test-utils的价值在于两点一是通过一行export *让 React Spectrum 用户直接获得react-aria/test-utils的整套 ARIA 模式测试器——用User统一交互模态与计时器推进用createTester获得类型安全、语义化的查询与操作 API替代手写 DOM 选择器与事件派发二是用 700/701px 边界 mockwindow.screen.width的simulateMobile/simulateDesktop让响应式组件Tray、Table 的桌面/移动变体等在 Jest 中可确定性测试。使用前提是testing-library/dom10testing-library/user-event14 React 18fake timers 场景务必向User传入advanceTimer。【免费下载链接】react-spectrumA collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.项目地址: https://gitcode.com/GitHub_Trending/re/react-spectrum创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表