使用Intern.js进行功能测试:getVisibleText()在dijit组件上失效
解决Dojo 1.13 + Intern v3测试中dijit组件文本获取失败的问题
我之前在Dojo 1.13搭配Intern v3做功能测试时也踩过这个坑,咱们来拆解下问题原因和解决办法:
问题根源
第一次调用getVisibleText()成功,是因为组件处于初始状态,此时DOM里的可见文本节点直接就是Type here;但当你输入日期并按Tab后,dijit组件会把输入值同步到内部的组件实例状态(而非直接更新DOM文本节点),普通的getVisibleText()方法没法穿透dijit的组件封装,读取到真实的显示值。
可行解决方案
方案1:直接读取dijit组件的实例值(推荐)
dijit组件(比如日期输入框这类表单组件)的真实值都存储在组件实例的value属性里,我们可以通过Intern的execute()方法在浏览器上下文直接获取组件实例,进而拿到值:
// 测试代码示例 return this.remote // 再次定位组件并点击 .findByClassName('functionalTestWidget') .click() .sleep(1000) // 执行浏览器端代码获取dijit实例的值 .execute(function() { // 通过DOM节点找到对应的dijit组件实例 const widgetNode = document.querySelector('.functionalTestWidget'); const widget = dijit.byNode(widgetNode); // 根据组件类型返回对应值,比如日期组件可能返回字符串或Date对象 return widget.get('value'); }) .then(function(widgetValue) { // 断言值符合预期 assert.strictEqual(widgetValue, '01/10/2010'); });
方案2:等待DOM更新后读取可见文本
如果一定要用getVisibleText(),需要确保组件的DOM已经完成更新,不要用固定的sleep(1000),改用waitForCondition()等待目标元素的文本/值更新完成:
// 测试代码示例 return this.remote .findByClassName('functionalTestWidget') .click() // 等待组件内部的输入元素更新到目标值 .waitForCondition(function() { const widgetNode = document.querySelector('.functionalTestWidget'); // 替换为你组件内部负责显示文本的DOM选择器,比如dijit输入框的.dijitInputInner const inputElement = widgetNode.querySelector('.dijitInputInner'); return inputElement && inputElement.value === '01/10/2010'; }, 5000) // 最多等待5秒,避免无限等待 .getVisibleText() .then(function(text) { assert.strictEqual(text, '01/10/2010'); });
额外注意事项
- 不同dijit组件的DOM结构不同,需要根据你测试的组件(比如
DateTextBox、TextBox)调整内部元素的选择器; - 尽量避免固定时长的
sleep(),用waitForCondition()更适配不同环境的渲染速度; - 如果页面中dijit不是全局暴露的,你可能需要在
execute()里通过组件的data-dojo-id或者其他方式获取实例。
内容的提问来源于stack exchange,提问作者Nicolas I
相关产品推荐
相关产品推荐

