任何关于在浏览器中测试extjs代码的建议,最好用硒? [英] Any suggestions for testing extjs code in a browser, preferably with selenium?

查看:180
本文介绍了任何关于在浏览器中测试extjs代码的建议,最好用硒?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们一直在很大程度上使用硒来处理高级网站测试(除了在模块级别进行广泛的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或XPath定位器替换Id定位器



CSS定位器以css =开始,XPath定位器以//开头(xpath =前缀是可选的)。 CSS定位器不那么冗长,更容易阅读,应该优先于XPath定位器。但是,由于CSS定位器根本无法切割,因此可能需要使用XPath定位器。



执行JavaScript



由于ExtJS执行的复杂渲染,某些元素需要的不仅仅是简单的鼠标/键盘交互。例如,Ext.form.CombBox不是真正的< select> 元素,而是带有分离的下拉列表的文本输入,该列表位于文档底部树。为了正确地模拟ComboBox选择,可以首先模拟一个点击下拉箭头,然后点击出现的列表。然而,通过CSS或XPath定位器定位这些元素可能很麻烦。另一种方法是定位ComoBox组件本身并调用方法来模拟选择:

  var combo = Ext.getCmp 'genderComboBox'); //返回ComboBox组件
combo.setValue('female'); //设置值
combo.fireEvent('select'); //因为setValue()不触发事件

在Selenium中 runScript 命令可用于以更简洁的形式执行上述操作:

  with(Ext .getCmp('genderComboBox')){setValue('female'); fireEvent(选择); 



应对AJAX和慢渲染



当用户操作导致页面转换或重新加载时,Selenium具有用于等待页面加载的所有命令的* AndWait风格。但是,由于AJAX提取不涉及实际的页面加载,因此这些命令不能用于同步。解决方案是利用视觉线索,如存在/不存在AJAX进度指示器或网格中的行的外观,附加组件,链接等。例如:

 命令:waitForElementNotPresent 
目标:css = div:contains('Loading ...')

有时,元素只会在一定时间后出现,这取决于ExtJS在用户操作导致视图更改后呈现组件的速度。不要在暂停命令中使用仲裁延迟,理想的方法是等待感兴趣的元素进入我们的掌握之中。例如,在等待它出现之后点击一个项目:

 命令:waitForElementPresent 
目标:css = span:contains('do the funky thing')
命令:点击
目标:css = span:contains('do the funky thing')

依赖任意暂停不是一个好主意,因为在不同浏览器或不同机器上运行测试所产生的时间差异将使测试用例变得薄弱。 p>

不可点击的项目



某些元素不能被点击命令。这是因为事件侦听器实际上是在容器上,在其子元素上观察鼠标事件,最终会浮起来。标签控件是一个例子。要点击一个选项卡,您必须在标签标签上模拟 mouseDown 事件:

 命令:mouseDownAt 
目标:css = .x-tab-strip-text:contains('Options')
值:0,0



字段验证



具有关联的表单域(Ext.form。*组件)用于验证的正则表达式或Vtypes将以一定的延迟触发验证(请参阅默认情况下设置为250ms的 validationDelay 属性),在用户输入文本后或立即在字段失去焦点或模糊(参见 validateOnDelay 属性)。为了在发出类型Selenium命令以在字段中输入一些文本之后触发字段验证,您必须执行以下任一操作:




  • 触发延迟验证



    当字段接收到密钥事件时,ExtJS将触发验证延迟定时器。要触发这个计时器,只需发出一个虚拟键盘事件(ExtJS忽略它使用的键无关紧要),然后是一个比validationDelay长的短暂暂停:

     命令:keyUp 
    目标:someTextArea
    值:x
    命令:暂停
    目标:500


  • 触发立即验证



    您可以在该字段中注入一个模糊事件以触发立即验证:

     命令:runScript 
    目标:someComponent。 nameTextField.fireEvent(blur)




验证结果



验证后,您可以检查是否存在错误字段:

 命令:verifyElementNotPresent 
目标://*[@id=\"nameTextField\"]/../*[@class=\"x-form-invalid-msg而不(包含(@style,display:none))]

命令:verifyElementPresent
目标://*[@id=\"nameTextField\"]/../*[@class=\"x-form-invalid-msg而不是(contains(@style,display:none))]

请注意,显示:无检查是必要的,因为一旦显示错误字段,则需要隐藏的ExtJS将简单地隐藏错误字段,而不是将其从DOM树中完全删除。



元素特定提示



< h2>点击Ext.form.Button


  • 选项1



    命令:单击
    目标:css =按钮:contains('Save')



    按照其标题选择按钮


  • 选项2



    命令:点击
    目标:css =#保存选项按钮



    按其ID来选择按钮




从Ext.form.ComboBox中选择一个值



 命令:runScript 
目标:with(Ext .getCmp('genderComboBox')){setValue('female') ; fireEvent(选择); }

首先设置值,然后显式地触发select事件,以防万一有观察者。 >

We've been using selenium with great success to handle high-level website testing (in addition to extensive python doctests at a module level). However now we're using extjs for a lot of pages and its proving difficult to incorporate Selenium tests for the complex components like grids.

Has anyone had success writing automated tests for extjs-based web pages? Lots of googling finds people with similar problems, but few answers. Thanks!

解决方案

The biggest hurdle in testing ExtJS with Selenium is that ExtJS doesn't render standard HTML elements and the Selenium IDE will naively (and rightfully) generate commands targeted at elements that just act as decor -- superfluous elements that help ExtJS with the whole desktop-look-and-feel. Here are a few tips and tricks that I've gathered while writing automated Selenium test against an ExtJS app.

General Tips

Locating Elements

When generating Selenium test cases by recording user actions with Selenium IDE on Firefox, Selenium will base the recorded actions on the ids of the HTML elements. However, for most clickable elements, ExtJS uses generated ids like "ext-gen-345" which are likely to change on a subsequent visit to the same page, even if no code changes have been made. After recording user actions for a test, there needs to be a manual effort to go through all such actions that depend on generated ids and to replace them. There are two types of replacements that can be made:

Replacing an Id Locator with a CSS or XPath Locator

CSS locators begin with "css=" and XPath locators begin with "//" (the "xpath=" prefix is optional). CSS locators are less verbose and are easier to read and should be preferred over XPath locators. However, there can be cases where XPath locators need to be used because a CSS locator simply can't cut it.

Executing JavaScript

Some elements require more than simple mouse/keyboard interactions due to the complex rendering carried out by ExtJS. For example, a Ext.form.CombBox is not really a <select> element but a text input with a detached drop-down list that's somewhere at the bottom of the document tree. In order to properly simulate a ComboBox selection, it's possible to first simulate a click on the drop-down arrow and then to click on the list that appears. However, locating these elements through CSS or XPath locators can be cumbersome. An alternative is to locate the ComoBox component itself and call methods on it to simulate the selection:

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

In Selenium the runScript command can be used to perform the above operation in a more concise form:

with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }

Coping with AJAX and Slow Rendering

Selenium has "*AndWait" flavors for all commands for waiting for page loads when a user action results in page transitions or reloads. However, since AJAX fetches don't involve actual page loads, these commands can't be used for synchronization. The solution is to make use of visual clues like the presence/absence of an AJAX progress indicator or the appearance of rows in a grid, additional components, links etc. For example:

Command: waitForElementNotPresent
Target: css=div:contains('Loading...')

Sometimes an element will appear only after a certain amount of time, depending on how fast ExtJS renders components after a user action results in a view change. Instead of using arbitary delays with the pause command, the ideal method is to wait until the element of interest comes within our grasp. For example, to click on an item after waiting for it to appear:

Command: waitForElementPresent
Target: css=span:contains('Do the funky thing')
Command: click
Target: css=span:contains('Do the funky thing')

Relying on arbitrary pauses is not a good idea since timing differences that result from running the tests in different browsers or on different machines will make the test cases flaky.

Non-clickable Items

Some elements can't be triggered by the click command. It's because the event listener is actually on the container, watching for mouse events on its child elements, that eventually bubble up to the parent. The tab control is one example. To click on the a tab, you have to simulate a mouseDown event at the tab label:

Command: mouseDownAt
Target: css=.x-tab-strip-text:contains('Options')
Value: 0,0

Field Validation

Form fields (Ext.form.* components) that have associated regular expressions or vtypes for validation will trigger validation with a certain delay (see the validationDelay property which is set to 250ms by default), after the user enters text or immediately when the field loses focus -- or blurs (see the validateOnDelay property). In order to trigger field validation after issuing the type Selenium command to enter some text inside a field, you have to do either of the following:

  • Triggering Delayed Validation

    ExtJS fires off the validation delay timer when the field receives keyup events. To trigger this timer, simply issue a dummy keyup event (it doesn't matter which key you use as ExtJS ignores it), followed by a short pause that is longer than the validationDelay:

    Command: keyUp
    Target: someTextArea
    Value: x
    Command: pause
    Target: 500
    

  • Triggering Immediate Validation

    You can inject a blur event into the field to trigger immediate validation:

    Command: runScript
    Target: someComponent.nameTextField.fireEvent("blur")
    

Checking for Validation Results

Following validation, you can check for the presence or absence of an error field:

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"))]

Note that the "display: none" check is necessary because once an error field is shown and then it needs to be hidden, ExtJS will simply hide error field instead of entirely removing it from the DOM tree.

Element-specific Tips

Clicking an Ext.form.Button

  • Option 1

    Command: click Target: css=button:contains('Save')

    Selects the button by its caption

  • Option 2

    Command: click Target: css=#save-options button

    Selects the button by its id

Selecting a Value from an Ext.form.ComboBox

Command: runScript
Target: with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }

First sets the value and then explicitly fires the select event in case there are observers.

这篇关于任何关于在浏览器中测试extjs代码的建议,最好用硒?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆