使用Selenium2测试含有iframe的Ajax网页

开发 后端
本文不是Selenium2的简单介绍或者入门内容,目标读者是至少使用过Selenium2进行测试的各位朋友。现在我们主要讨论2个问题,第一是使用Selenium对由Ajax动态加载的页面进行测试。第二就是测试含有iframe标签的网页。

前  言

本文主要通过一个简单的例子,来讨论以下两个问题:

  • 使用Selenium对由Ajax动态加载的页面进行测试
  • 测试含有iframe标签的网页

本文不是Selenium2的简单介绍或者入门内容,目标读者是至少使用过Selenium2进行测试的各位朋友。

准备工作

假设你有一项业务,需要在用户进行输入的时候用Ajax弹出辅助输入的窗口,然后再将这些值传回主窗口。

为了叙述简便,这里使用一个简单的iframe标签对弹出窗口进行简化。

首先需要两个网页,一个是主页面main.html:

  1. <HTML> 
  2.     <HEAD> 
  3.         <TITLE>寸木的Selenium+Ajax测试</TITLE> 
  4.         <SCRIPT language="javascript"> 
  5.         function loadFrame() {  
  6.             // 取得DIV对象  
  7.             var divElement = document.getElementById("TestDiv");  
  8.             // 插入iFrame元素  
  9.             divElement.innerHTML = "<iframe id='TestFrame'style='width:200px;height:250px;'/>";  
  10.             // 取得动态插入的iFrame元素  
  11.             var frameElement = document.getElementById("TestFrame");  
  12.                
  13.             frameElement.src = "SubPage.html";  
  14.         }  
  15.         </SCRIPT> 
  16.         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
  17.     </HEAD> 
  18.     <BODY> 
  19.         <H1>主页面</H1> 
  20.         下面的区域是测试用的Frame。  
  21.         <div id="TestDiv" style="width:200px;height:250px;border:solid 1px #000000;">&nbsp;</div><br /> 
  22.         <input type="button" value="Load Frame" onclick="loadFrame();" id="btnLoad"/><br /> 
  23.         接收到的信息:<label id="lblMsg">Waiting mesage</label> 
  24.     </BODY> 
  25. </HTML> 

接着是被弹出的窗口SubPage.html

  1. <HTML> 
  2.     <HEAD> 
  3.         <TITLE>寸木的Selenium+Ajax测试</TITLE> 
  4.         <SCRIPT language="javascript"> 
  5.             function removeDefaultInfo(webElement) {  
  6.                 var strDefalutInfo = "请输入信息...";  
  7.                 if(webElement.value == strDefalutInfo) {  
  8.                     webElement.value = "";  
  9.                 }  
  10.             }  
  11.             function setDefaultInfo(webElement) {  
  12.                 var strDefalutInfo = "请输入信息...";  
  13.                 if(webElement.value == "") {  
  14.                     webElement.value = strDefalutInfo;  
  15.                 }  
  16.             }  
  17.             function sendToMainPage() {  
  18.                 parent.document.getElementById("lblMsg").innerHTML = document.getElementById("frameText").value;  
  19.             }  
  20.         </SCRIPT> 
  21.         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
  22.     </HEAD> 
  23.     <BODY style="background-color:#009900;"> 
  24.         <H1>子页面</H1> 
  25.         Hi, 这里是子页面,为了和主页面加以区别,我被标注成了绿色。<br> 
  26.         <input type="text" id="frameText" value="请输入信息..." onfocus="removeDefaultInfo(this);" onblur="setDefaultInfo(this);"/> 
  27.         <input type="button" value="传送到主窗口" onclick="sendToMainPage();" id="btnSendBack" /> 
  28.     </BODY> 
  29. </HTML> 

关键问题

我们的目标是用Java编写一段能够自动测试这一完整业务逻辑的测试代码。因此,我们首先想到的可能会是类似下面的代码

  1. /**  
  2.  *  
  3.  */ 
  4. package com.cnblogs.www.hexin0614;  
  5.    
  6. import org.openqa.selenium.By;  
  7. import org.openqa.selenium.WebDriver;  
  8. import org.openqa.selenium.firefox.FirefoxDriver;  
  9.    
  10. /**  
  11.  * @author hexin  
  12.  *  
  13.  */ 
  14. public class TestSa {  
  15.        
  16.     /**  
  17.      * @param args  
  18.      * @throws Exception  
  19.      */ 
  20.     public static void main(String[] args) throws Exception {  
  21.            
  22.            
  23.         // Declare  
  24.         WebDriver driver = new FirefoxDriver();  
  25.            
  26.         // Load page  
  27.         driver.get("file:///C:/tmp/Main.html");  
  28.            
  29.         Thread.sleep(15000);  
  30.            
  31.         // Load subpage  
  32.         driver.findElement(By.id("btnLoad")).click();  
  33.            
  34.         // Input message  
  35.         driver.findElement(By.id("frameText")).sendKeys("Message from Selenium.");  
  36.         // Send message back to main page  
  37.         driver.findElement(By.id("btnSendBack")).click();  
  38.            
  39.         Thread.sleep(2000);  
  40.            
  41.         // Go back to main frame  
  42.         System.out.println(driver.findElement(By.id("lblMsg")).getText());  
  43.            
  44.         driver.close();  
  45.     }  

实际运行的时候会报告找不到"frameText"元素的错误。这是怎么回事呢?

原来Selenium2在使用get()方法打开一个网页的时候,是不会继续加载里面的iframe中的内容的(这一点与Selenium有所区别)。

那么,我们就需要人为的要求Selenium2对iframe中的内容进行加载。

  1. // Step into the subpage  
  2. driver.switchTo().frame("TestFrame"); 

这样就可以找到id为"frameText"的元素了。

重新运行,发现还是有错,这一次报告的是"lblMsg"元素找不到?奇怪吗?

不奇怪,因为我们通过上面的switchTo()方法已经切换到了iframe的内部,而subpage中是不存在id为"lblMsg"对象的。

怎么办?只有重新回到Mainpage上来。

根据Selenium2的在线文档,有很多方法可以切换回MainPage。(别告诉我你没有耐心的去读那些文档)

笔者经过摸索发现了一个比较简单的方法:利用getWindowHandle()方法可以快速的进行切换。该方法的JavaDoc如下

  1. Return an opaque handle to this window that uniquely identifies it within this driver instance.This can be used to switch to this window at a later date 

看来只要在切换至iframe内部的时候,提前记录下Mainpage的句柄就可以在将来的任何时候回到主窗口了。于是我们追加下面两行代码。

  1. // Back up main page's handler  
  2. String strMainHandler = driver.getWindowHandle();  
  3.    
  4. // ........  
  5.    
  6. // Go back to main frame  
  7. driver.switchTo().window(strMainHandler); 

好了,问题解决了,是不是很简单?***送出完整的Java代码。

  1. /*  
  2.  * Test  
  3.  */ 
  4. package com.cnblogs.www.hexin0614;  
  5.    
  6. import org.openqa.selenium.By;  
  7. import org.openqa.selenium.WebDriver;  
  8. import org.openqa.selenium.firefox.FirefoxDriver;  
  9.    
  10. /**  
  11.  * @author hexin  
  12.  *  
  13.  */ 
  14. public class TestSa {  
  15.        
  16.     /**  
  17.      * @param args  
  18.      * @throws Exception  
  19.      */ 
  20.     public static void main(String[] args) throws Exception {  
  21.            
  22.            
  23.         // Declare  
  24.         WebDriver driver = new FirefoxDriver();  
  25.            
  26.         // Load page  
  27.         driver.get("file:///C:/tmp/Main.html");  
  28.            
  29.         Thread.sleep(15000);  
  30.            
  31.         // Load subpage  
  32.         driver.findElement(By.id("btnLoad")).click();  
  33.            
  34.         // Back up main page's handler  
  35.         String strMainHandler = driver.getWindowHandle();  
  36.         // Step into the subpage  
  37.         driver.switchTo().frame("TestFrame");  
  38.            
  39.            
  40.         // Input message  
  41.         driver.findElement(By.id("frameText")).sendKeys("Message from Selenium.");  
  42.         // Send message back to main page  
  43.         driver.findElement(By.id("btnSendBack")).click();  
  44.            
  45.         Thread.sleep(2000);  
  46.            
  47.         // Go back to main frame  
  48.         driver.switchTo().window(strMainHandler);  
  49.         System.out.println(driver.findElement(By.id("lblMsg")).getText());  
  50.            
  51.         driver.close();  
  52.     }  

原文链接:http://www.cnblogs.com/hexin0614/archive/2012/03/24/2415670.html

【编辑推荐】

  1. Java中的Enum的使用与分析
  2. 按权重选取目标的Java算法
  3. 通用Java文件上传和下载组件的设计与实现
  4. 赶紧重写Java的时间和日期API吧!
  5. 谈谈Java的自动装箱和拆箱
责任编辑:林师授 来源: 寸木的博客
相关推荐

2024-05-21 09:52:19

2022-06-13 09:00:00

Selenium测试Web

2023-12-25 09:52:32

2013-01-15 11:22:29

AjaxASP.NET

2011-08-11 13:02:43

Struts2Junit

2009-09-01 11:20:11

Struts 2AJAX支持

2011-05-13 09:53:02

strutsAjax

2011-06-16 14:08:20

JSONAjax

2011-01-20 10:17:25

ibmdwWeb

2013-03-13 11:34:05

自动化测试Selenium.Net测试

2009-05-20 14:49:16

ibmdwAjaxWeb开发

2011-01-24 13:20:49

2023-02-15 08:21:22

2012-09-28 10:18:53

IBMdw

2009-07-27 09:07:04

Profile SerASP.NET AJA

2017-05-12 18:00:44

pyspiderAJAXHTTP

2009-06-01 15:44:18

2010-06-09 09:15:58

JSF 2Ajax组件

2009-06-16 15:56:10

MIDlet生命周期J2ME程序测试

2011-07-18 14:43:40

JSON模拟加载初析
点赞
收藏

51CTO技术栈公众号