在Ember.js中使用Protractor定位元素:解决动态ember id问题
解决Ember.js应用中Protractor元素定位的动态ID问题
作为刚接触Ember.js的新手,碰到这种动态生成的ember### ID确实挺头疼的——我当初刚用Ember的时候也踩过这个坑!别担心,咱们换几个思路就能搞定元素定位的问题,而且都是Ember社区里常用的靠谱方案:
优先使用自定义测试属性(推荐最佳实践)
Ember自动生成的动态ID本来就是框架内部用来管理元素的,不适合用来做测试定位。咱们可以给需要测试的元素添加专门的data-test属性(名字可以自己定,比如data-test-id也可以),这个属性不会随页面刷新变化,也不会影响业务逻辑。
比如在Ember模板里这么写:<!-- 按钮元素 --> <button data-test="submit-action">提交表单</button> <!-- 输入框元素 --> {{input data-test="username-field" value=model.username}}然后在Protractor里就可以用CSS选择器定位:
// 定位提交按钮 element(by.css('[data-test="submit-action"]')).click(); // 定位用户名输入框并输入内容 element(by.css('[data-test="username-field"]')).sendKeys('foo');嫌写CSS选择器麻烦的话,还可以给Protractor封装一个自定义定位器,用起来更简洁:
// 在测试文件开头添加这个定位器 by.addLocator('testId', function(testValue, parentElement) { const using = parentElement || document; return using.querySelectorAll(`[data-test="${testValue}"]`); }); // 之后就能直接这么用 element(by.testId('submit-action')).click();利用元素文本或父级结构定位(临时救急方案)
如果只是临时测试不想改模板,也可以通过元素的固定文本或者稳定的父级容器来定位:- 按钮类元素可以用文本定位:
element(by.buttonText('提交表单')) - 输入框可以结合父容器的类名:
element(by.css('.login-form input[type="email"]'))
不过要注意,这种方法依赖页面结构或文本内容,如果后续UI调整(比如改了按钮文字),测试就会失效,所以只适合临时场景。
- 按钮类元素可以用文本定位:
手动指定固定ID(慎用)
你也可以直接在Ember模板里给元素手动设置固定的id,比如:<button id="fixed-submit-btn">提交</button>然后用
element(by.id('fixed-submit-btn'))定位。但这个方法有个坑:如果组件被复用,多个相同组件会出现重复ID的问题,违反HTML规范,所以除非是全局唯一的元素,否则不推荐用这个方法。
总的来说,最稳妥的还是用data-test这类测试专属属性,这也是Ember官方推荐的测试实践,既能保证测试的稳定性,又不会和框架内部的ID机制冲突。
内容的提问来源于stack exchange,提问作者kyneese
相关产品推荐
相关产品推荐

