如何使用Cypress测试Material UI的MuiAutocomplete电影选择功能
用Cypress测试Material UI Autocomplete组件
我现在用React+TypeScript搭配Material UI开发,得写Cypress测试用例验证MuiAutocomplete组件的交互,要完成这三步:
- 找到并打开Autocomplete的下拉菜单
- 选中下拉里的一个选项
- 确认输入框显示选中的值
组件HTML结构
<div class="MuiAutocomplete-root MuiAutocomplete-hasPopupIcon css-4ec9ly-MuiAutocomplete-root" role="combobox" aria-expanded="false" xpath="1"> <div class="MuiFormControl-root MuiFormControl-fullWidth MuiTextField-root css-wb57ya-MuiFormControl-root-MuiTextField-root"> <label class="MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-sizeSmall MuiInputLabel-standard MuiFormLabel-root MuiFormLabel-colorPrimary css-577pmh-MuiFormLabel-root-MuiInputLabel-root" data-shrink="false" for="movies-filter" id="movies-filter-label" style="">Movies </label> <div class="MuiInput-root MuiInputBase-root MuiInputBase-colorPrimary MuiInputBase-fullWidth MuiInputBase-formControl MuiInputBase-sizeSmall MuiAutocomplete-inputRoot css-4op3e8-MuiInputBase-root-MuiInput-root"> <input aria-invalid="false" autocomplete="off" id="movies-filter" placeholder="Start typing" type="text" class="MuiInput-input MuiInputBase-input MuiInputBase-inputSizeSmall MuiAutocomplete-input MuiAutocomplete-inputFocused css-nz481w-MuiInputBase-input-MuiInput-input" aria-autocomplete="list" autocapitalize="none" spellcheck="false" value="" style=""> </div> </div> </div>
之前的尝试代码
第一次尝试
cy.contains('.MuiAutocomplete-root', 'Movies').click(); // 识别并打开Autocomplete组件 cy.contains('A1-Test1').click(); // 选择选项 cy.contains('.MuiAutocomplete-root', 'Movies') .find('input') .should('have.value', 'Movie1'); // 验证输入框值
第二次尝试
cy.get('#Movies-filter').click().focused().type('Mo'); cy.contains('Movie1').click();
问题分析
之前的写法有几个坑:
- 第一次尝试里,
cy.contains('.MuiAutocomplete-root', 'Movies')匹配的是整个组件容器,点击容器不一定能触发下拉展开,得直接点输入框或者下拉触发按钮。 - 元素ID大小写错了:HTML里输入框ID是
movies-filter(全小写),第二次尝试写成了#Movies-filter,导致找不到元素。 - 直接用
cy.contains选选项容易出问题——如果页面上有其他相同文本的元素,会误选,得限定在Autocomplete的下拉面板里找选项。
正确的测试代码
基础版本(直接打开下拉选选项)
// 1. 点击输入框打开下拉菜单 cy.get('#movies-filter').click(); // 2. 在下拉面板(带role="listbox"的元素)里找到目标选项并点击 cy.get('[role="listbox"]').contains('Movie1').click(); // 3. 验证输入框的值是否正确 cy.get('#movies-filter').should('have.value', 'Movie1');
带搜索过滤的版本
如果需要输入关键词过滤选项,可以这么写:
// 输入关键词过滤下拉选项 cy.get('#movies-filter').type('Mo'); // 等待下拉面板加载完成,再选择目标选项 cy.get('[role="listbox"]').should('be.visible').contains('Movie1').click(); // 验证输入框的值 cy.get('#movies-filter').should('have.value', 'Movie1');
补充说明
- 用
[role="listbox"]定位下拉面板比依赖动态CSS类更稳定,因为Material UI的Autocomplete下拉菜单默认会带这个ARIA角色,不会随版本或主题变化。 - 直接通过ID
#movies-filter定位输入框是最可靠的方式,避免CSS类名变动导致测试失败。 - 如果下拉选项是异步加载的,记得加
.should('be.visible')确保元素可交互后再点击,避免测试不稳定。
内容的提问来源于stack exchange,提问作者N-DEV
相关产品推荐
相关产品推荐

