這篇文章討論selenium對(duì)于網(wǎng)頁控件的操作。網(wǎng)頁控件不像driver或是瀏覽器那樣設(shè)置好直接用就可以了,操作一個(gè)網(wǎng)頁控件我們首先要知道它在網(wǎng)頁上的位置,找到它,然后再操作。所以我想先介紹一個(gè)必要的知識(shí)點(diǎn)– 控件的定位。
那怎么找到網(wǎng)頁上的元素呢?除非是極簡(jiǎn)風(fēng)格或是本身網(wǎng)站就簡(jiǎn)單,現(xiàn)在大多數(shù)網(wǎng)站源代碼都很多很長(zhǎng)。就即便是看起來很簡(jiǎn)單的網(wǎng)站,比如韓寒的“一個(gè)”(www.wufazhuce.com),打開源代碼一看也是很長(zhǎng)的。假設(shè)我現(xiàn)在想找下方某一篇文章的元素位置:
要是一行一行看源代碼找,那肯定要花很長(zhǎng)時(shí)間,不劃算。不過沒關(guān)系,現(xiàn)在咱們使用的三種瀏覽器都有自己內(nèi)嵌的工具可以幫助我們找到想要的元素,不管網(wǎng)頁多長(zhǎng)多復(fù)雜,定位速度都很快。FireFox的內(nèi)嵌工具叫Firebug,作為該瀏覽器其中一個(gè)插件存在。打開FireFox,選擇”add-on”并搜索FireBug,可以找到該工具:
我們最好也把下面的FirePath也安裝上,以后會(huì)用到。裝好后我們會(huì)在瀏覽器右上角看到一個(gè)小蟲子的圖標(biāo),不過暫時(shí)還是灰色的,因?yàn)闆]激活。FireBug嘛,bug,小蟲子。點(diǎn)擊激活它,然后打開咱們的測(cè)試網(wǎng)站webelements.html就可以開始使用了。比如我想找頁面上的鏈接“點(diǎn)擊這里跳轉(zhuǎn)”,只要把鼠標(biāo)移到該鏈接上方->右鍵-> Inspect Element with Firebug(用Firebug查看元素),就可以看到這個(gè)鏈接元素的位置和代碼,高亮顯示:
我們的演示網(wǎng)站比較簡(jiǎn)單,大家可以在更復(fù)雜的網(wǎng)站上實(shí)驗(yàn)。
以上是FireFox。相比之下Chrome比較簡(jiǎn)單,不需要安裝任何插件,因?yàn)樗旧碜詭б粋€(gè)開發(fā)者工具。直接在元素上右鍵->Inspect(查看)就會(huì)彈出開發(fā)者工具:
IE也不需要插件,右鍵->Inspect Element(查看元素)即可。網(wǎng)頁源代碼不會(huì)因?yàn)闉g覽器的改變而發(fā)生變化,所以其實(shí)不管使用哪種瀏覽器,只要我們能定位到我們想要的元素就可以了。
定位到了我們想要的元素然后呢?我們可以在瀏覽器上鼠標(biāo)右鍵點(diǎn)點(diǎn)點(diǎn)找到該元素,但和我們寫的程序有什么關(guān)系呢?怎么能通過程序知道它的位置呢?所以我們要做的,就是把鼠標(biāo)點(diǎn)出來的元素代碼通過某種媒介告訴我們寫的程序,而這個(gè)媒介就是定位器(Locators):
我們?cè)趀clipse里新建一個(gè)java項(xiàng)目叫SeleniumId,然后建包c(diǎn)om.test -> Test.java,把該引的selenium jar包引進(jìn)來,把driver設(shè)置創(chuàng)建好。我們還是用測(cè)試網(wǎng)頁webelements.html做例子。直接上代碼:
網(wǎng)頁元素有8種定位器,任何一個(gè)網(wǎng)頁元素都可以通過這8種之一找到:
1. Id;
2. Name;
3. ClassName;
4. TagName;
5. LinkText;
6. PartialLinkText;
7. CSS Locator;
8. Xpath。
還不少,后來我自己學(xué)習(xí)的時(shí)候在他人基礎(chǔ)上編了個(gè)口訣記的:“一個(gè)id,兩個(gè)link(Link, PartialLink),三個(gè)name(Name, ClassName, TagName)外加兩個(gè)大bug(CSS Locator, Xpath)?!蔽夜茏詈髢蓚€(gè)叫大bug因?yàn)橐粋€(gè)網(wǎng)頁元素可以沒有id、name、link,但一定會(huì)有xpath。而且現(xiàn)在基本看不到不用css的網(wǎng)站了,所以css locator大部分情況也能通用。這二者秒殺一切網(wǎng)頁元素,所有的都能找到,很bug。以后做例子的時(shí)候大家就能體會(huì)到了。
還記得前面咱們之前說driver還有一個(gè)方法叫findElement()嗎?咱們還寫了這么一句driver.findElement(),findElement的意思是找到元素。這句代碼就是用來接收定位器的,讓定位器作為參數(shù)傳入findElement方法。
現(xiàn)在開始介紹第一種定位器id。id是一個(gè)網(wǎng)頁元素的屬性,它的語法格式是:
舉個(gè)例子,用firefox打開咱們的webelements的網(wǎng)站,比如我們想定位第三個(gè)網(wǎng)頁元素鏈接,用firebug查看結(jié)果如下:
我們可以看到鏈接這個(gè)網(wǎng)頁元素有個(gè)id=hyperlink的屬性。所以,我們的程序可以這么繼續(xù)寫:
By.id(“hyperlink”)作為參數(shù)傳入findElement()方法,里面有一個(gè)關(guān)鍵字叫By,英文里是“依靠”的意思,所以這句話的意思就是“依靠一個(gè)id值為hyperlink的屬性找到某控件”。記起來也就不難了。By這個(gè)關(guān)鍵字很重要,只要一設(shè)計(jì)網(wǎng)頁控件定位就需要它。findElement()方法返回的是一個(gè)網(wǎng)頁元素的對(duì)象,類型是WebElement,咱們這個(gè)例子里指的就是這個(gè)鏈接,我用link表示。因?yàn)楝F(xiàn)在還沒有系統(tǒng)介紹網(wǎng)頁控件的操作和斷言,所以我們只能在終端打印出來鏈接信息來證明已經(jīng)找到了該鏈接。不過大家可以看一下一個(gè)網(wǎng)頁控件可以有多少操作:
getText()方法可以打印出一個(gè)鏈接上的文本內(nèi)容,所以我們用這個(gè)方法在終端打印出來:
結(jié)果如下:
沒問題吧?如果沒找到肯定打印不出來這句話對(duì)不對(duì)?其實(shí)不光打不出來,找不到還會(huì)拋異常,selenium就是這么個(gè)玩意兒。
你看,我們隨便寫了個(gè)id,其實(shí)壓根不存在。錯(cuò)誤妥妥地爆出來。你可以用try…catch…捕獲錯(cuò)誤信息,但我們總不希望測(cè)試的時(shí)候老有異常拋出來吧?以后講控件操作時(shí)會(huì)告訴大家怎么處理??丶牟僮魑覀儠?huì)在講完定位器后挨個(gè)掃蕩一遍,暫時(shí)咱們用到哪個(gè)就先提一句。以上就是一個(gè)使用id查找鏈接的小例子,大家可以用別的網(wǎng)站再做做實(shí)驗(yàn)。
有人說,那如果在同一個(gè)網(wǎng)頁上有兩個(gè)元素?fù)碛型粋€(gè)id怎么辦呢?比如它們都等于hyperlink,程序怎么知道該選哪個(gè)呢?完全沒必要顧慮,因?yàn)樵谕粋€(gè)網(wǎng)頁上不可能有兩個(gè)元素?fù)碛型粋€(gè)id,有些功能因?yàn)閕d沖突會(huì)在某些情況下失效!這是web應(yīng)用前端開發(fā)時(shí)的規(guī)定,你可以去任何正規(guī)大型網(wǎng)站上看看,同一個(gè)網(wǎng)頁上絕不會(huì)出現(xiàn)同一個(gè)id。所以,如果一個(gè)元素有id,那我們最好先用id來定位,因?yàn)樗梢晕ㄒ粯?biāo)識(shí)當(dāng)前網(wǎng)頁上的某一個(gè)元素。當(dāng)然,如果是同一個(gè)網(wǎng)站中的不同網(wǎng)頁,id可以重復(fù)。
看來放到不同網(wǎng)頁就不會(huì)引起沖突,我們可不可以這么想:網(wǎng)頁之間是彼此獨(dú)立的,定位控件時(shí)都是根據(jù)當(dāng)前網(wǎng)頁來執(zhí)行的?為了證明這個(gè)觀點(diǎn),請(qǐng)看下面這個(gè)例子,我們先打印出來鏈接文本,然后導(dǎo)到百度,然后再嘗試打印鏈接文本:
執(zhí)行一下肯定會(huì)報(bào)錯(cuò),因?yàn)樘D(zhuǎn)到百度后原先網(wǎng)頁上的鏈接對(duì)象就不存在了!同樣的System.out.println(link.getText())操作,只不過中間隔了一個(gè)跳轉(zhuǎn)百度并等3秒鐘就報(bào)錯(cuò)了。所以我們可以得出這個(gè)結(jié)論了:所有的控件定位都是針對(duì)當(dāng)前網(wǎng)頁來說的,當(dāng)從一個(gè)網(wǎng)頁跳轉(zhuǎn)到另一個(gè)網(wǎng)頁的時(shí)候,所有之前存在的都會(huì)失效。這不光適用于id,還適合于其它定位器。這也間接證明了不同網(wǎng)頁元素可以用同一個(gè)id,因?yàn)橥粫r(shí)間selenium只能處理一個(gè)網(wǎng)頁。至于網(wǎng)頁之間為什么是彼此獨(dú)立的,這個(gè)涉及http協(xié)議以及web應(yīng)用程序相關(guān)知識(shí),有興趣的可以上網(wǎng)查查資料。咱們是做測(cè)試的,其實(shí)更需要知識(shí)的廣度。如果以后有時(shí)間我也會(huì)寫相關(guān)的文章的。
如果id不存在還能用id來定位這個(gè)鏈接嗎?當(dāng)然不能,不存在怎么能使用id呢?那就得從另外七種定位器中選擇了。
這篇文章的源代碼是SeleniumId這個(gè)項(xiàng)目,下篇介紹和Name相關(guān)的三種定位器使用方法。
本篇知識(shí)點(diǎn)及注意事項(xiàng):
1.所有的控件定位都是針對(duì)當(dāng)前網(wǎng)頁來說的,當(dāng)從一個(gè)網(wǎng)頁跳轉(zhuǎn)到另一個(gè)網(wǎng)頁的時(shí)候,所有之前存在的都會(huì)失效。