UFT调用JQuery解决网页动态数据加载以及自定义Event的问题

  伴随JQuery技术在大量网站中的应用,尤其是如果网站中采用了JQuery所定义的Event对用户事件进行处理,采用默认的UFT对象识别机制,可能将无法正常产生脚本和回放,本文将以一个实际案例为例,讲解如何在UFT脚本中调用JQuery,以及如何处理JQuery事件。

案例说明

  如下图1所示,这是国航的官方首页,该网站在首页“机票预订”中,当用户在“出发城市”【图中1处】中输入城市名称或者拼音,或者任何缩写,网页会自动查询数据库,并动态在该输入框下方弹出一个窗口【图中2处】,动态显示符合查询条件的城市所在地的机场名称。我们将以此案例为例,来讲述所存在的问题以及解决方案。

图1

解决思路:

  • 【思路一】采用UFT自带的Record(录制模式)模式尝试录制该脚

    1.打开UFT,并加载Web插件

 

图2

    2.脚本录制步骤本文不再详细讲述,脚本将录制如下操作:

图3

 

图4

图5

图6

 

 

录制完成以后,将在UFT中看到如下代码:

1 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").WebElement("机票预订").Click
2 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").WebEdit("queryWord").Set ""
3 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Sync
4 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").WebEdit("queryWord").Set "重庆"

代码解释:

第一行:表示点击“机票预订”

第二行:表示在输入框中输入“”

第三行:Page同步等待页面加载

第四行:表示在输入框中输入“重庆”

从以上UFT录制自动产生的代码来看,与我们期望的操作似乎有差距,没有下拉列表(目的地机场)选择的操作,当我们回放此脚本时,也能说明这个问题,因为脚本回放时,并没有出现目的地机场选择的列表。问题出在哪里?初步看来通过录制的方式无法生成我们所希望的脚本。

  我们来分析一下问题何在,我们需要用到FireFox和Chrome的Debug工具(后边我会讲到为什么需要两个工具)。网页中,用户在输入框中输入值以后,页面动态弹出其他菜单,一般情况下都需要使用JavaScript+Ajax来实现,而要触发这个JavaScript,通常情况下都需要在指定的控件上绑定相应的Event(事件),例如鼠标点击事件,鼠标双击事件等。因此,我们先借助Chrome的Debug工具,查看一下该控件都绑定了哪些Event。

1,打开Chrome,并打开http://www.airchina.com.cn/,页面加载完成以后,按F12,打开Chrome的Debug工具,如下图所示

2,点击下方的Event Listeners并切换为Selected Node Only

 

3,通过选择工具,选择希望查看的网页控件,如下图所示,可以看到出发城市输入框控件绑定了2个事件,分别是focus和keyup。

因此我们可以得出如下结论:

  a,当用户首次点击出发城市输入框时,系统会触发focus事件,而该事件绑定了一个显示默认列表的函数,这便是为什么我们点击该控件在没有输入任何值的情况下,页面会自动弹出一个有很多城市的选择窗口

  b,当用户在该输入框中输入任何查询值后,系统会触发keyup事件,而该事件绑定了一个ajax调用函数,会自动根据查询条件查询结果,并将查询结果显示出来供用户选择(之前的脚本应该是没有能录制下此操作,所以脚本回放的时候,不会有对应的页面弹出,如图5),那如何才能出发keyup事件呢?熟悉UFT的人可能首先会想到利用对象的FireEvent方法来实现,但是非常不幸的是,我们查看UFT自带的帮助文档,FireEvent方式只能模拟这些事件:onchangeonclickondblclick, onbluronfocusonmousedownonmouseuponmouseoveronmouseoutonsubmitonresetonpropertychange. 这里很明显没有keyup事件,那怎么办???

  我们重新来分析一下该网页的代码,发现该网页采用了JQuery技术,同时keyup事件是JQuery框架中所支持的一种事件,如下图:

  问题似乎找到了出路,只要我们能定位到该控件对象,并调用jquery的keyup事件,那就应该可以模拟用户在页面中输入内容以后触发keyup(插一句,因为我们用UFT的set方法给对象赋值,实际上只改变了控件的value,但是并没有触发任何的event),所以我们又遇到两个问题:

  Q1,如何快速定位“出发城市”控件?

  Q2,如何在UFT中调用JQuery的event方法?

  这两个问题我们可以使用UFT的RunScript来处理(原理是因为Web Page中已经加载了JQuery框架,所以只要我们能调用JS脚本,就能用JQuery技术来快速定位元素,并调用JQuery所支持的方法。扩展:若网页没有加载JQuery,我们也想使用JQuery框架来快速定位元素,怎么办呢?大家可以阅读我的另外一篇文章《UFT中使用JQuery框架来快速定位元素》),这便有了思路二,我们来看思路二的实现方式。

 

 

  • 【思路二】

实现脚本如下:

1 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").WebElement("机票预订").Click
2 
3 '出发地
4 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").RunScript("$('[name=queryWord][id=0]').focus()")
5 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").RunScript("$('[name=queryWord][id=0]').val('重庆')")
6 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").RunScript("$('[name=queryWord][id=0]').keyup()")

在UFT中运行以上脚本,运行以后我们发现第6行代码执行以后并没有出现我们所期望的结果,页面弹出如下图的出发地机场列表。

 

  重新分析UFT代码我们不难发现,第5行代码并非通过键盘输入的值,而是直接调用函数进行的赋值,所以肯定不可能有任何的键盘事件产生,而keyup的触发是需要键盘事件,所以我们必须在UFT脚本中模拟出键盘事件才可以触发keyup,要在UFT中模拟键盘事件方法有很多,这里我们采用一种常用的方法,修改后的代码如下:

1 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").RunScript("$('[name=queryWord][id=0]').focus()")
2 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").RunScript("$('[name=queryWord][id=0]').val('北京')")
3 Dim device
4 Set device = CreateObject("Mercury.DeviceReplay")
5 device.SendString " "

  这里我们去掉了keyup,同时加入了3,4,5这几行代码,这几行代码实际上会在输入框赋值为“北京”以后,再输入一个“ ”空格,“北京 ”,而这个空格是通过键盘事件输入,所以输入以后,会自动触发keyup,这就是为什么我删除了之前的keyup代码,重新执行,如果顺利,我们会发现我们所期望的结果总算出来了。

  但是离我们所需要的还差一步,就是在弹出菜单中选择。这个动态弹出菜单,通过对象识别机制无法产生脚本,只能自行处理,只要我们能定位到元素,然后在其上执行click方法就应该可以实现,由于我们已经加载了JQuery框架,所以我们可以用JQuery所提供的选择器来快速定位元素,在定位之前我们需要借助工具来查看我们需要定位元素的特点,这里我们将使用Firefox,因为Firefox的定位功能比IE,Chrome都更好使用,尤其是动态显示的Div块。

  打开Firefox,并访问网站来定位元素信息(如何使用Firefox的Firedebug大家可以在网上搜索一下,有很多相关的文章),从下图中可以看到,这个动态显示的窗口内容实际上是在一个id=locContent的元素中,所以我们可以采用如下脚本进行调用:

 

1 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").WebElement("机票预订").Click
2 
3 '出发地
4 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").RunScript("$('[name=queryWord][id=0]').focus()")
5 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").RunScript("$('[name=queryWord][id=0]').val('北京')")
6 Dim device
7 Set device = CreateObject("Mercury.DeviceReplay")
8 device.SendString " "
9 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").RunScript("$('#locContent').children().last().click()")

 

我们执行该代码,但是我们会发现脚本执行并未成功,页面卡在出发城市机场选择页面。看样子有可能动态弹出页面执行的并不是Click方法,这可怎么办?Firefox可以再次上场了,我们可以用Firefox的事件查看工具来看指定对象的事件,并通过调整该事件来进一步确认,如下图,通过分析我们可以确定实际上触发的是mouseover和blur事件,因此更改代码如下:

 1 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").WebElement("机票预订").Click
 2 
 3 '出发地
 4 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").RunScript("$('[name=queryWord][id=0]').focus()")
 5 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").RunScript("$('[name=queryWord][id=0]').val('北京')")
 6 Dim device
 7 Set device = CreateObject("Mercury.DeviceReplay")
 8 device.SendString " "
 9 
10 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").RunScript("$('#locContent').children().last().mouseover()")
11 Browser("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").Page("中国国际航空公司-飞机票查询预订_航班查询_最新打折特价机票").RunScript("$('document').blur()")

  到此,所有问题都得到解决,文中并未对JQuery的使用进行讲解,大家可以自行查看相关网站和文档,稍微总结一下:

  1. UFT中可以通过RunScript来调用JavaScript,因此可以使用JQuery来扩展UFT在对象识别方面的功能 
  2. 如果脚本中需要模拟键盘事件,可以使用Mercury.DeviceReplay对象
  3. 可以结合Chrome,Firefox等Debug工具帮助分析网页元素,尤其是相关元素绑定的Event,属性等,有利于脚本开发
posted @ 2015-07-26 15:15  火山企鹅  阅读(753)  评论(0)    收藏  举报