Jest测试读取含无障碍span标签的innerText内容不全问题求助
Jest可访问性测试中innerText无法读取完整文本的问题及解决
问题场景
我在Jest测试中遇到问题:当文本包含带aria-hidden='true'和sr-only类的span标签时,通过innerText获取内容只能读到部分文本,无法匹配完整期望结果。
内容文件定义
"termsLabel": { "offerHeader": "{payment}/<span aria-hidden='true'>mo.</span><span class='sr-only'>month.</span> for {t_payments} years" }
React组件渲染代码
const Card = ({ offer: { content } }) => { const { termsLabel } = content; const HeaderField = termsLabel?.offerHeader; return ( <div className="container"> <div className="offer__row"> {/* eslint-disable-next-line react/no-danger */} <strong className="offer__field-header" dangerouslySetInnerHTML={{ __html: HeaderField }} /> </div> </div> ); }; export default Card;
Jest测试代码
export const showInfo = async (modalContent) => { const offerFieldHeadline = await contentWindow.$eval(offerRow, element => element.innerText); expect(offerFieldHeadline).toContain(modalContent.offerHeadline); };
其中modalContent.offerHeadline为"$34.82/mo. for 6 years",但测试返回的innerText仅为"$33.17/mo.",无法匹配完整文本。
问题原因
innerText的可见性规则:innerText仅返回元素中可见的文本内容,sr-only类的元素通常通过CSS移出可视区域,其内容会被innerText忽略。但核心问题是后续的"for {t_payments} years"文本未被读取,大概率是以下原因之一:- 测试选择器
offerRow指向范围错误,选中了部分文本所在的子元素(比如aria-hidden的span)而非外层容器; - 测试环境未加载
sr-only的CSS样式,导致jsdom/Puppeteer对元素可见性的判断异常,引发文本截断; - 模板变量替换不完整,导致
"for {t_payments} years"未被正确渲染为实际文本。
- 测试选择器
解决方法
1. 改用textContent获取完整文本
textContent会返回元素的所有文本内容,不受可见性影响,之后可清理掉不需要的隐藏文本:
const offerFieldHeadline = await contentWindow.$eval(offerRow, element => element.textContent); // 移除sr-only的"month."文本,匹配期望格式 const cleanedText = offerFieldHeadline.replace(/month\./g, '').trim(); expect(cleanedText).toContain(modalContent.offerHeadline);
2. 确保测试环境加载CSS样式
如果坚持使用innerText,需让测试环境加载包含sr-only类的CSS文件:
- 对于Jest+jsdom:在
setupFilesAfterEnv配置文件中导入全局CSS; - 对于Puppeteer:在页面加载时通过
page.addStyleTag注入样式或加载样式文件。
3. 调整断言逻辑
直接针对可见文本的格式做断言,比如使用正则表达式:
expect(offerFieldHeadline).toMatch(/\$\d+\.\d+\/mo\. for \d+ years/);
4. 验证选择器正确性
打印选中元素的HTML,确认是否包含完整文本:
const elementHTML = await contentWindow.$eval(offerRow, element => element.outerHTML); console.log(elementHTML); // 检查选中元素是否覆盖了完整内容区域
内容的提问来源于stack exchange,提问作者ericoder
相关产品推荐
相关产品推荐

