7.4 操纵待测Web页面上的HTML元素的值
问题
如何操纵待测Web页面上的input HTML元素,以模拟一些用户操作,比如在文本框里输入数据或单击按钮等等。
设计
通过InternetExplorer对象的Document对象创建一个引用,指向待测Web页面的document body。然后通过mshtml.dll库里的getElementById()方法获得你想要操纵的HTML元素的引用,并且把这个元素的value或其他属性设为给定的值。
方案
HTMLDocument theDoc = (HTMLDocument)ie.Document;
Console.WriteLine("\nSelecting 'Name' radio button");
HTMLInputElement radioButton =
(HTMLInputElement)theDoc.getElementById("RadioButtonList1_0");
radioButton.@checked = true;
Console.WriteLine("Setting text box to 'foo'");
HTMLInputElement textBox =
(HTMLInputElement)theDoc.getElementById("TextBox1");
textBox.value = "foo";
Console.WriteLine("Setting dropdown list to 'blue'");
HTMLSelectElement dropdown =
(HTMLSelectElement)theDoc.getElementById("DropDownList1");
dropdown.value = "blue";
Console.WriteLine("Clicking search button");
HTMLInputElement butt =
(HTMLInputElement)theDoc.getElementById("Button1");
butt.click();
documentComplete.WaitOne(); // 参见7.2节
这个例子的前提是,我们已经像7.1和7.2节所描述的那样创建好了一个InternetExplorer对象并且把它与一个IE进程相关联。我们首先声明一个HTMLDocument对象,并且把用于测试的InternetExplorer对象的document body作为引用赋给它。HTMLDocument类型的定义在mshtml.dll里。要访问这个库,需要添加.NET Microsoft.mshtml组件的一个工程引用。这个受控的代码库提供到mshtml命名空间的映射,因此可以添加针对这个命名空间的using mshtml
语句,以避免使用HTMLDocument或这个库中其他类的全名称。准备好HTMLDocument对象之后,可以通过getElementByID()方法获得有ID字符串的HTML元素的引用。然后,可以通过给value属性赋值来模拟针对这个HTML元素的用户操作。在上述方案中,要模拟用户选中某个radio button控件,必须使用@checked,因为checked是C#语言的一个关键字。
注解
在.NET编程环境下,操作待测Web页面上的控件是相对简单的,至少相比于通过非受控代码来完成这些工作来说是简单的。请注意,因为我们是通过getElementById()方法来获得HTML元素/控件的引用的,所以这个控件必须要有ID attribute,从而可以唯一地标识这个控件。如果Web页面是通过Visual Studio.NET UI设计器创建的,那么这就不会成为一个问题,因为这种情况下所有的控件都有一个ID attribute。但是,ID attribute是可选项,所以如果Web程序是手工创建的(比如通过Notepad),那就可能需要修改这个程序,给它们加上ID attribute,以便能够使用这里所讲述的技术。
Visual Studio.NET里有一个很好的工具:Object Browser,这个工具可以帮助你更好地理解以及扩展这里给出的解决方案。如果用Object Browser打开mshtml引用并且把上面的树形控件展开,你会看到上千个可用的类和方法。这些内容实在太多了,不可能全部记住,但幸运的是,编写自动化测试程序时,用到的只是其中位数不多的几个类。如果需要知道应该使用mshtml命名空间里的哪个对象接口,可以在Web程序里试探性地找出这个对象的类型。例如,注意到在上述方案中,按钮控件和文本框控件的类型都是HTMLInputElement,而下拉框控件的类型则是HTMLSelectElement。如何才能知道这一点呢?你可以通过下面的代码知道到底该用哪个类:
object o1 = (object)theDoc.getElementById("TextBox1");
Console.WriteLine("The textbox has type "+ o1.GetType().ToString());
object o2 = (object)theDoc.getElementById("DropDownList1");
Console.WriteLine("The dropdown has type " + o2.GetType().ToString());
本节的技术只适用于操作IE浏览器客户区域的控件。要操纵菜单栏或者其他非客户区域的窗体,可以使用第3章讲述的技术。







