使用 Selenium 测试 ExtJS 的最大障碍是 ExtJS 不会渲染标准 HTML 元素,而 Selenium IDE 将天真地(并且正确地)生成针对仅充当装饰元素的命令 - 帮助 ExtJS 处理整个桌面的多余元素 -外观和感觉。以下是我在针对 ExtJS 应用程序编写自动化 Selenium 测试时收集的一些提示和技巧。
一般提示
定位元素
当通过在 Firefox 上使用 Selenium IDE 记录用户操作来生成 Selenium 测试用例时,Selenium 会将记录的操作基于 HTML 元素的 id。然而,对于大多数可点击元素,ExtJS 使用生成的 id,如“ext-gen-345”,即使没有进行任何代码更改,这些 id 也可能在后续访问同一页面时发生更改。记录测试的用户操作后,需要手动检查依赖于生成的 id 的所有此类操作并替换它们。可以进行两种类型的替换:
使用 CSS 或 XPath 定位器替换 Id 定位器
CSS 定位器以“css=”开头,XPath 定位器以“//”开头(“xpath=”前缀是可选的)。 CSS 定位器更简洁,更容易阅读,应该优于 XPath 定位器。然而,在某些情况下,可能需要使用 XPath 定位器,因为 CSS 定位器根本无法做到这一点。
执行 JavaScript
由于 ExtJS 执行的复杂渲染,某些元素需要的不仅仅是简单的鼠标/键盘交互。例如,Ext.form.ComboBox并不是真正的<select>
元素,而是一个带有独立下拉列表的文本输入,该下拉列表位于文档树底部的某个位置。为了正确模拟组合框选择,可以首先模拟单击下拉箭头,然后单击出现的列表。然而,通过 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
在硒中runScript
命令可以用来以更简洁的形式执行上述操作:
with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
应对 AJAX 和缓慢的渲染
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
财产)。为了在发出 type Selenium 命令在字段中输入一些文本后触发字段验证,您必须执行以下任一操作:
-
触发延迟验证
当字段接收到 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 树中完全删除。
特定于元素的提示
单击 Ext.form.Button
从 Ext.form.ComboBox 中选择一个值
Command: runScript
Target: with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
首先设置值,然后在存在观察者的情况下显式触发 select 事件。