我们一直在成功地使用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在以后访问同一页面时也可能会更改。在记录了用于测试的用户操作之后,需要手动进行所有取决于生成的ID的操作并替换它们。可以进行两种类型的替换:
CSS定位符以“ css =“开头,XPath定位符以“ //”开头(“ xpath =”前缀是可选的)。CSS定位器不太冗长,更易于阅读,应优先于XPath定位器使用。但是,在某些情况下,由于CSS定位器根本无法剪切,因此需要使用XPath定位器。
由于ExtJS进行了复杂的渲染,因此某些元素所需要的不仅仅是简单的鼠标/键盘交互。例如,Ext.form.CombBox实际上不是<select>元素,而是文本输入,带有在文档树底部某个位置的分离下拉列表。为了正确模拟ComboBox选择,可以首先模拟对下拉箭头的单击,然后单击出现的列表。但是,通过CSS或XPath定位器定位这些元素可能很麻烦。另一种方法是找到ComoBox组件本身,并在其上调用方法以模拟选择:
<select>
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命令可用于以更简洁的形式执行上述操作:
runScript
with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
当用户操作导致页面转换或重新加载时,Selenium的所有命令都具有“ * AndWait”样式,以等待页面加载。但是,由于AJAX提取不涉及实际的页面加载,因此这些命令不能用于同步。解决方案是利用视觉线索,例如是否存在AJAX进度指示器或网格中行的外观,其他组件,链接等。例如:
Command: waitForElementNotPresent Target: css=div:contains('Loading...')
有时,元素仅在一定时间后才会显示,这取决于在用户操作导致视图更改后ExtJS呈现组件的速度。pause理想的方法是等到感兴趣的元素进入我们的控制范围,而不是在命令中使用任意延迟。例如,在等待项目出现后单击它:
pause
Command: waitForElementPresent Target: css=span:contains('Do the funky thing') Command: click Target: css=span:contains('Do the funky thing')
依靠任意的暂停不是一个好主意,因为在不同的浏览器或不同的机器上运行测试所导致的时间差异会导致测试用例不稳定。
某些元素不能由click命令触发。这是因为事件侦听器实际上位于容器上,监视其子元素上的鼠标事件,最终冒泡到父对象。选项卡控件是一个示例。要单击选项卡,必须mouseDown在选项卡标签上模拟事件:
click
mouseDown
Command: mouseDownAt Target: css=.x-tab-strip-text:contains('Options') Value: 0,0
validationDelay在用户输入文本后或当字段丢失时,具有关联的正则表达式或vtypes进行验证的表单字段(Ext.form。*组件)将以一定的延迟触发验证(请参见默认设置为250ms 的属性)。焦点-或模糊(请参阅validateOnDelay属性)。为了在发出type Selenium命令以在字段内输入一些文本后触发字段验证,您必须执行以下任一操作:
validationDelay
validateOnDelay
当字段接收到keyup事件时,ExtJS将触发验证延迟计时器。要触发此计时器,只需发出一个虚拟keyup事件(因为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树中删除。
命令:单击目标:css = button:contains(’保存’)
通过标题选择按钮
命令:单击目标:css =#save-options按钮
按其ID选择按钮
Command: runScript Target: with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
首先设置值,然后在有观察者的情况下显式触发select事件。