自己動手寫Web自動化測試框架(3):操縱Web控制元件

Just4life發表於2013-07-31
上面的兩次課程我們介紹了mshtml和SHDocVw的一些用途,以及如何開啟並且附加到IE上,實現IE的巨集觀上的控制。

  這次我們將會用程式碼找到我們想要的控制元件,然後對控制元件進行一些操作。

  首先我們引入一個很好的IE控制元件:Internet Explorer Developer Toolbar,這個控制元件可以幫助我們方便的找到我們想要的控制元件的屬性。

  安裝好這個控制元件之後,我們就可以方便的找到每一個控制元件的ID,或者其他屬性了,如下圖

  IE Developer

  注意,開啟IE Developer Toolbar之後,要點選下面的滑鼠按鈕,才可以用滑鼠來選擇我們想要的控制元件。有了這個控制元件,我們就不用去檢視原始檔來找到我們想要的資訊了。其他的功能這裡不多說了。

  接下來我們以百度的三個控制元件為例,分別告訴大家如何使用ID得到TextBox,如何點選使用ID得到的Button,如何使用子控制元件縮小範圍的方法得到一個HyperLink。

  首先我們修改上次的程式碼,把IE指到百度去:

Console.WriteLine("Navigating ...");

object o = null;
ie.Navigate("baidu.com", ref o, ref o, ref o, ref o);
Thread.Sleep(2000);

  程式碼我們在自己動手寫Web自動化測試框架(2):開啟和操縱IE都講解過了。只有一點,我們在完成IE的跳轉之後,等待了2秒鐘的時間,原因是IE的工作是需要時間的,我們在後面的測試框架部分會講解如何判斷IE已經完成了頁面的跳轉,在這裡為了讓大家更好的瞭解我們本節的主題,只是用了簡單的等待。

  然後我們用IE Developer Tools得到了關鍵字文字框的ID是kw,所以我們用下面的程式碼在關鍵字文字框裡面輸入了我們想要的關鍵字:

//得到一個Text Box
Console.WriteLine("Inputing Keyword ...");
HTMLDocument doc = (HTMLDocument)ie.Document;
HTMLInputElement keyword = (HTMLInputElement)doc.getElementById("kw");
keyword.value = "colblog.net";
Thread.Sleep(1000);

首先我們用ie.Document物件得到了HTMLDocument。目的沒什麼可說的,因為我們需要HTMLDocument得到下面的控制元件。而這裡之所以使用強制型別轉換,是因為Document物件在這裡返回一個object的引用,但其實是一個HTMLDocument的例項。所以轉換一下就好了,在mshtml裡面,這種情況還不少,在msdn上有詳細的講解,使用的時候查一下就好了。

  然後使用HTMLDocument.getElementById方法,直接從Document裡面按照ID取出想要的控制元件,返回一個 IHTMLElement,IHTMLElement是HTMLElement的抽象,所有的HTML的tag都可以是一個IHTMLElement,返回這樣的一個引用,我們在知道將會返回什麼型別的情況下,可以使用強制型別轉換來把物件轉成我們想要的引用。就像上面我們所做的,返回的其實是一個 Input tag,所以我們要把他轉換成HTMLInputElement就好了。

  下面一句我們直接對這個物件的value進行設定,就可以完成在關鍵詞文字框裡面輸入我們想要的關鍵詞的動作。

  接下來我們要點選搜尋按鈕:

//得到一個按鈕

Console.WriteLine("Clicking Submit ...");
HTMLInputElement submit = (HTMLInputElement)doc.getElementById("sb");
submit.click();
Thread.Sleep(2000);

  有了上面文字框的解釋,這一段程式碼就容易多了吧。這裡不在贅述。

  聰明的讀者一定會問:我們現在使用ID查詢控制元件,如果我們的控制元件沒有ID怎麼辦?如果ID是重複的怎麼辦?

  上面的兩種情況都是完全可能的,而且在實際中幾乎佔據了大部分的情況。(不過ASP.NET裡面的控制元件倒是都有ID,使用這種方法比較方便。)我們下面的例子就是去點選百度首頁右上角的登入超級連結。

  首先我們分析一下,登入超級連結是放在一個id為u的div裡面,而登入超級連結是沒有ID的。我們的思路就是先找到這個id為u的div,然後找他的chidren找到我們想要的這個超級連結,下面是原始碼:

//得到一個連結

Console.WriteLine("Clicking Login Button ...");
IHTMLElement userPanel = doc.getElementById("u");
IHTMLElementCollection HyperLinks = ((IHTMLElement2)userPanel).getElementsByTagName("a");
IHTMLElement login = (IHTMLElement)HyperLinks.item(null, 0);

login.click();

  首先我們得到了那個id為u的div,命名為userPanel。這一步和上面沒啥區別。

  下面一個語句我們得到了userPanel的控制元件的所有tag為a的控制元件,也就是所有的超級連結。這裡有一個小小的需要注意的地方,我們看到這個語句吧IHTMLElement物件強制型別轉換成了IHTMLElement2,很有意思,為啥會這樣呢?其實IHTMLElement有4個這樣的兄弟,他們之間的方法不同,可以互相轉換,我們想要的getElementsByTagName在IHTMLElement2下面,所以我們就強制型別轉換到IHTMLElement2。這個方法返回一個IHTMLCollection。我們用HyperLinks來儲存這個引用。

  因為userPanel的子控制元件只有登入超級連結這一個,所以我們直接使用index為0來取道這個物件就好了。IHTMLElementCollection裡面的item方法詳見msdn,我們只需要把第二個index設定為0,就可以取到第一個子物件。

相關文章