使用Cypress测试MUI DesktopDatePicker时输入框值异常问题
解决Cypress测试MUI DesktopDatePicker时的隐形字符匹配问题
问题根源
你遇到的问题是因为Material-UI的DesktopDatePicker在渲染日期值时,会插入不可见的Unicode双向文本格式字符(比如\u2066、\u2069这类),这些字符在页面上看不到,但会存在于输入框的value属性中,导致你写的字面量字符串和实际值表面一致、实际编码不同,从而断言失败。
解决方案
方法1:清理实际值中的隐形字符后断言
通过正则表达式移除所有隐形格式字符,再和预期值做精确匹配:
it("allows the user to select the Leave Start date in the MUI DatePicker", () => { // 打开日期选择器 cy.get("[data-testid='CalendarIcon']").first().click(); const currentDate = new Date(); const currentYear = currentDate.getFullYear(); const currentMonth = currentDate.getMonth() + 1; const expectedDate = `15 / ${currentMonth} / ${currentYear}`; cy.get(".MuiPickersDay-root").contains("15").click(); // 优化选择器:用closest替代多层parent,更健壮 cy.get("[data-testid='CalendarIcon']") .first() .closest('.MuiTextField-root') .find('input') .invoke('val') .then(actualValue => { // 移除所有Unicode隐形格式字符 const cleanedValue = actualValue.replace(/[\u2066\u2067\u2068\u2069\u200B-\u200D\uFEFF]/g, ''); expect(cleanedValue).to.equal(expectedDate); }); });
方法2:直接使用宽松的匹配断言
如果日期格式固定,也可以用正则匹配来忽略隐形字符:
it("allows the user to select the Leave Start date in the MUI DatePicker", () => { cy.get("[data-testid='CalendarIcon']").first().click(); const currentDate = new Date(); const currentYear = currentDate.getFullYear(); const currentMonth = currentDate.getMonth() + 1; cy.get(".MuiPickersDay-root").contains("15").click(); // 用正则匹配预期日期,忽略中间的隐形字符 cy.get("[data-testid='CalendarIcon']") .first() .closest('.MuiTextField-root') .find('input') .should('have.value', new RegExp(`15\\s*\\/\\s*${currentMonth}\\s*\\/\\s*${currentYear}`)); });
额外优化建议
- 避免使用多层
parent()定位元素,改用closest()结合MUI的类名(比如.MuiTextField-root),让选择器更稳定,不易受DOM结构变更影响。 - 如果项目中频繁遇到这类问题,可以封装自定义断言命令统一处理:
// 在cypress/support/commands.js中添加 Cypress.Commands.add('haveCleanValue', { prevSubject: true }, (subject, expectedValue) => { const cleanedValue = subject.val().replace(/[\u2066\u2067\u2068\u2069\u200B-\u200D\uFEFF]/g, ''); expect(cleanedValue).to.equal(expectedValue); return subject; }); // 测试中使用 cy.get('input').haveCleanValue(expectedDate);
内容的提问来源于stack exchange,提问作者Lloukas
相关产品推荐
相关产品推荐

