對象定位
前面提到過如何用IE進行找元素,那么找到元素屬性后,我們該如何使用呢?下面就來了解下webdriver提供的一系列的定位方法。
常見的方法有:
1>Id
IWebElement ele= driver.FindElement(By.Id("idValue")); 或者 IWebElement ele = driver.FindElementById("idValue");
2>Name
IWebElement ele= driver.FindElement(By.Name("nameValue")); 或者 IWebElement ele= driver.FindElementByName("nameValue");
3>TagName
IWebElement ele= driver.FindElement(By.TagName("xx")); 或者 IWebElement ele= driver.FindElementByTagName("xx");
4>ClassName
IWebElement ele= driver.FindElement(By.ClassName("xx")); 或者 IWebElement ele= driver.FindElementByClassName("xx");
5>CssSeletor
IWebElement ele= driver.FindElement(By.CssSeletor("xx")); 或者 IWebElement ele= driver.FindElementByCssSeletor("xx");
6>XPath
單條件 IWebElement ele= driver.FindElement(By.XPath("//xx[@id='id']")); 多條件 IWebElement ele= driver.FindElement(By.XPath("//xx[@id='id'][@id='id'][]")); 或者 IWebElement ele= driver.FindElementByXPath("//xx[@id='id']"); IWebElement ele= driver.FindElementByXPath("//xx[@id='id'][@id='id'][]"));
以上每種定位方法都有兩種定位方式:FindeElement(By.xx),FindeElementByxx。他們都屬於命名空間OpenQA.Selenium.Remote下的方法,只不過前者是根據(By.xx)這個對象來找,后者是根據元素的屬性(Id,name...)來找。總的來講,在這里沒有太大區別。
不過,我無意中的一次發現,他們雖然在使用上都可以滿足我們的需求,但是在找元素的性能上海市略有差別的。
下面是我寫的一個簡單的測試例子:
找百度首頁的輸入框
//使用FindElementByxx方法
var a = DateTime.Now.Millisecond; var searchBox1 = driver.FindElementsByName("wd"); var b = DateTime.Now.Millisecond; //使用FindElement(By.xx)方法
var c = DateTime.Now.Millisecond; var searchBox2 = driver.FindElements(By.Name("wd")); var d = DateTime.Now.Millisecond; Console.WriteLine("'FindElementByName' spent " + (b - a).ToString() + "millisecond"); Console.WriteLine("'FindElement(By.Name)' spent " + (d - c).ToString() + "millisecond");
結果如下:
不難發現使用FindElement(By) 方法找對象還是要快蠻多的,所以這里推薦使用它,但是說實話本人個人習慣喜歡用FindElementBy_xx方法,不為別的,只因為在vs上用它比較快,不知道這算不算vs一族的通病。。。
至於為什么使用FindElement(By) 方法要快這么多?本人功力有限,還待來日再研究。。。。。。嘿嘿!
對於以上幾種方法,我這里暫時就不提供例子了,方法1-4很常見也很好理解的,至於5-6,后面再續。
下面我要講的是一個有點小特殊的例子,因為我發現很多人寫的blog里面都用到它(非C# 語言),但是今天我去發現這個行不通,下面就來看具體實例:
找到百度首頁的搜索框,並輸入搜索內容:在前面一篇里我是用FindElementById來找對象的(下面這個代碼,是可以實現效果的)。
//找到對象 var searchBox = driver.FindElementById("kw1"); ...... //發送搜索內容 searchBox.SendKeys("selenium");
下面,我們用FindElementByName來實現:我們用IE的"Developer Tools" 不難發現name的值為"wd"。如是我們會用到以下代碼:
1 var searchBox1 = driver.FindElementsByName("wd"); 2 ...... 3 searchBox1.SendKeys("selenium");
按理說,這個因該可以實現效果的,大家都這么寫的,我也是這么認為的,但是代碼運行到第3行的時候,會彈出異常:
未處理:ElementNotVisableException:Element is not displayed。
於是,對於這個異常我用了以下方法:將鼠標移動到元素上
1 var searchBox1 = driver.FindElementByName("wd"); 2 Actions builder = new Actions(driver); 3 builder.MoveToElement(searchBox1).Perform(); 4 Thread.Sleep(2000); 5 searchBox1.SendKeys("234");
結果還是異常,當獲取對象的displayed屬性時,發現在移動鼠標之前與移動之后它的值都是false。
var isDisplayed = searchBox1.Displayed.ToString();
於是,當我用FindElementsByName方法后,才發現問題所在(此方法:找出所有的符合條件的元素,返回ReadOnlyCollection)。
此時searchBox[1]才是我們需要的對象:
因為用FindElementByName不能唯一確定要找的對象,所以后面的操作出現異常。那么此時還是用對象的name來定位的話,應該如下:
1 var colSearchBox1 = driver.FindElementsByName("wd"); 2 colSearchBox1[1].SendKeys("123");