我们一直在使用selenium非常成功地处理高级网站测试(除了模块级别的广泛python doctests).然而,现在我们在很多页面上使用extjs,并证明很难将Selenium测试用于像网格这样的复杂组件.
有没有人成功为基于extjs的网页编写自动化测试?很多谷歌搜索发现有类似问题的人,但答案很少.谢谢!
使用Selenium测试ExtJS的最大障碍是ExtJS不会呈现标准的HTML元素,而且Selenium IDE会天真(并且正确地)生成针对仅作为装饰的元素的命令 - 多余的元素可以帮助ExtJS完成整个桌面 - 外观和感觉.以下是我在针对ExtJS应用程序编写自动Selenium测试时收集的一些提示和技巧.
一般提示通过在Firefox上使用Selenium IDE记录用户操作来生成Selenium测试用例时,Selenium将记录的操作基于HTML元素的ID.但是,对于大多数可点击元素,ExtJS使用生成的ID,如"ext-gen-345",即使没有进行任何代码更改,也可能在随后访问同一页面时发生更改.在记录测试的用户操作之后,需要手动操作以完成依赖于生成的ID并替换它们的所有此类操作.可以进行两种类型的替换:
CSS定位器以"css ="开头,XPath定位符以"//"开头("xpath ="前缀是可选的).CSS定位器不那么冗长,易于阅读,应该优先于XPath定位器.但是,可能存在需要使用XPath定位器的情况,因为CSS定位器根本无法切割它.
由于ExtJS执行的复杂渲染,一些元素需要的不仅仅是简单的鼠标/键盘交互.例如,Ext.form.CombBox实际上不是一个元素,而是一个带有分离下拉列表的文本输入,该列表位于文档树的底部.为了正确模拟ComboBox选择,可以首先模拟下拉箭头上的单击,然后单击出现的列表.但是,通过CSS或XPath定位器定位这些元素可能很麻烦.另一种方法是找到ComoBox组件本身并在其上调用方法来模拟选择:
var combo = Ext.getCmp('genderComboBox'); // returns the ComboBox components combo.setValue('female'); // set the value combo.fireEvent('select'); // because setValue() doesn't trigger the event
在Selenium中,该runScript
命令可用于以更简洁的形式执行上述操作:
with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
当用户操作导致页面转换或重新加载时,Selenium对于等待页面加载的所有命令都具有"*AndWait"风格.但是,由于AJAX提取不涉及实际页面加载,因此这些命令不能用于同步.解决方案是利用视觉线索,例如AJAX进度指示器的存在/不存在或网格中行的外观,附加组件,链接等.例如:
Command: waitForElementNotPresent Target: css=div:contains('Loading...')
有时元素只会在一定时间后出现,具体取决于ExtJS在用户操作导致视图更改后呈现组件的速度.而不是使用pause
命令的任意延迟,理想的方法是等到我们掌握的感兴趣的元素.例如,要在等待项目出现后单击该项目:
Command: waitForElementPresent Target: css=span:contains('Do the funky thing') Command: click Target: css=span:contains('Do the funky thing')
依赖于任意暂停不是一个好主意,因为在不同浏览器或不同机器上运行测试所产生的时序差异将使测试用例变得不稳定.
click
命令无法触发某些元素.这是因为事件监听器实际上在容器上,在其子元素上观察鼠标事件,最终冒泡到父元素.选项卡控件就是一个例子.要单击选项卡,您必须mouseDown
在选项卡标签处模拟事件:
Command: mouseDownAt Target: css=.x-tab-strip-text:contains('Options') Value: 0,0
具有关联正则表达式或vtypes进行验证的表单字段(Ext.form.*组件)将validationDelay
在用户输入文本后立即触发验证(请参见默认设置为250ms 的属性)或当字段丢失时立即触发验证焦点 - 或模糊(见validateOnDelay
财产).为了在发出Selenium类型命令以在字段内输入某些文本后触发字段验证,您必须执行以下任一操作:
触发延迟验证
当字段接收到keyup事件时,ExtJS会触发验证延迟计时器.要触发此计时器,只需发出一个虚拟键盘事件(无论你使用哪个键作为ExtJS忽略它),然后是一个比validationDelay更长的短暂停顿:
Command: keyUp Target: someTextArea Value: x Command: pause Target: 500
触发即时验证
您可以在字段中注入模糊事件以触发立即验证:
Command: runScript Target: someComponent.nameTextField.fireEvent("blur")
验证后,您可以检查是否存在错误字段:
Command: verifyElementNotPresent Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))] Command: verifyElementPresent Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
请注意,"display:none"检查是必要的,因为一旦显示错误字段然后需要隐藏它,ExtJS将简单地隐藏错误字段而不是完全从DOM树中删除它.
元素特定提示
选项1
命令:单击目标:css =按钮:包含('保存')
按标题选择按钮
选项2
命令:单击Target:css =#save-options按钮
按ID选择按钮
Command: runScript Target: with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
首先设置值,然后在有观察者的情况下显式触发select事件.
这个博客给了我很多帮助.他在这个主题上写了很多,看起来它仍然活跃.这家伙似乎也很欣赏好的设计.
他基本上讨论了如何使用发送javascript来进行查询,并使用Ext.ComponentQuery.query方法以与内部应用程序相同的方式检索内容.这样你可以使用xtypes和itemIds,而不必担心尝试解析任何疯狂的自动生成的东西.
我发现这篇文章特别有帮助.
可能很快在这里发布一些更详细的东西 - 仍然试图让我的头脑如何正确地做到这一点