1.id--標籤中id 的值css
若是開發人員編程規範,頁面的元素id 不重複的且不是動態生成的id時,使用id 定位很是容易。web
//<select style="width: 33%" id="CityCode" name="CityCode" class="form-control lopicker">
//使用id定位元素
WebElement element = driver.findElement(By.id("CityCode"));
2.name--標籤中name的值chrome
//<select style="width: 33%" id="CityCode" name="CityCode" class="form-control lopicker">
//使用name定位元素
WebElement cityelement = driver.findElement(By.name("CityCode"));
3.className--標籤中class屬性的值編程
//<select style="width: 33%" id="ProvinceCode" name="ProvinceCode" class="form-control lopicker">
//使用className定位
WebElement element = driver.findElement(By.className("form-control"));
4.tagName--標籤名瀏覽器
//<select style="width: 33%" id="ProvinceCode" name="ProvinceCode" class="form-control lopicker">
//使用標籤名定位元素
WebElement element = driver.findElement(By.tagName("select"));
5.linkText--a標籤中所有的文本值app
//<a href="/Competition/Detail/c05a5ae3-32c6-4b81-b042-646ad8de275a" title="尋寶機器人賽" class="link item_title">尋寶機器人賽</a> WebElement comElement = driver.findElement(By.linkText("尋寶機器人賽"));
6.partialLinkText--a標籤中部分的文本值框架
//<a href="/Competition/Detail/c05a5ae3-32c6-4b81-b042-646ad8de275a" title="尋寶機器人賽" class="link item_title">尋寶機器人賽</a> WebElement comElement = driver.findElement(By.partialLinkText("尋寶"));
7.CSSSelector--css選擇器(很是重要)dom
//<select style="width: 33%" id="ProvinceCode" name="ProvinceCode" class="form-control lopicker"> WebElement element = driver.findElement(By.cssSelector(".form-control")); WebElement element1= driver.findElement(By.cssSelector("select.form-control"));
/** * (有屬性的標籤)很是經常使用CssSelector:標籤名[屬性名='屬性值'][屬性名='屬性值'][屬性名='屬性值'][屬性名='屬性值'] */ //<select style="width: 33%" id="CityCode" name="CityCode" class="form-control lopicker"> WebElement cityelement = driver.findElement(By.cssSelector("select#CityCode")); WebElement cityelement1 = driver.findElement(By.cssSelector("#CityCode")); WebElement cityelement2 = driver.findElement(By.cssSelector("select[name='CityCode']")); WebElement cityelement3 = driver.findElement(By.cssSelector("select[class='form-control lopicker'][name='CityCode']"));
8.xpath--相對路徑/絕對路徑異步
使用chrome自帶或者火狐的xpath的插件能夠得到元素的相對或者絕對路徑。ide
chrome:
fireFox:
//<select style="width: 33%" id="AreaCode" name="AreaCode" class="form-control lopicker"> //經過單個屬性定位 WebElement areaElement = driver.findElement(By.xpath("//*[@id=\"AreaCode\"]")); //經過多個屬性定位 WebElement areaElement1 = driver.findElement(By.xpath("//select[@style='width: 33%' and @name='AreaCode']"));
//<a href="/Competition/Detail/c05a5ae3-32c6-4b81-b042-646ad8de275a" title="尋寶機器人賽" class="link item_title">尋寶機器人賽</a> //經過contains表達式 WebElement comElement1 = driver.findElement(By.xpath("//a[@class='link item_title' and contains(text(),'機器人賽')]")); //經過startsWith表達式 WebElement comElement2 = driver.findElement(By.xpath("//a[@class='link item_title' and starts-with(text(),'尋寶')]")); //若是讀者的谷歌版本只支持xpath1.0,因此ends-with不能使用 // WebElement comElement3 = driver.findElement(By.xpath("//a[@class='link item_title' and ends-with(text(),'機器人賽')]")); //若是ends-with不支持,可使用下面方式代替 WebElement comElement4 = driver.findElement(By.xpath("//a[substring(text(), string-length(text()) - string-length('人賽') +1) = '人賽']"));
上面總結了8種定位元素的方法。
下面說明一些特殊狀況:
1.id是動態生成的。
這種狀況下,能夠選擇其餘的定位方式。如cssSelector xPath等
如,生成的id老是以register字符串結尾:
<input id="m.f0.menu.f2.volumeTabs.BLOCK_COMMON.tcw.form.register" name="m.f0.menu.f2.volumeTabs.BLOCK_COMMON.tcw.form.register" class="aranea-checkbox" type="checkbox"> </td>
此時,能夠經過xpath的方式來查找
driver.findElement(By.xpath("//input[ends-with(@id,'register')]"));
若是這個動態id有規律可循的話,也能夠經過id來定位元素。具體就不舉例了。
2.能夠將查找元素封裝成相應的方法,直接調用。方便添加日誌信息。
/** * 查找元素的方法 element */ public WebElement findElementBy(By by) { return driver.findElement(by); } /** * 查找多個元素的方法 elements */ public List<WebElement> findElementsBy(By by) { return driver.findElements(by); } /** * 查找到多個元素後,繼續向下查找(定位出一個元素這是一堆相同的elements中 選擇 其中方的 一個 而後在這個選定的中 繼續定位)
*/
public WebElement getOneElement(By bys, By by, int index) {
return findElementsBy(bys).get(index).findElement(by);
}
3.在查找元素的時候,會考慮到該元素資源是否已經加載完成。
下面給你們總結一下,關於自動化測試中的「等待」:
1.硬性等待---封裝成方法,方便調用。
/**
* 硬性等待,等待時間爲:sleepTime。
*/
public void Wait(int sleepTime) {
if (sleepTime <= 0) {
return;
}
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
2.隱式等待---這個等待是全局的,是針對當前driver的。一旦設置以後,只要該driver執行findElement或者findElements方法,首先回去找元素,若是沒找到,會在設置的時間內一直輪詢查找,直到timeOut.因爲是全局性的,有些元素不須要等待,因此會形成時間的浪費。由於瀏覽器是自上而下渲染的,若是元素1在元素2的上面,當你第一次查找過元素2,以後再查找元素1的時候,是不須要等待的。可是設置了該全局參數以後,仍是會去等待。
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
3.顯示等待(推薦使用)
/** * 對外提供智能等待 查找元素的方法 * @param driver * @param time * 元素的超時等待時間 * @param by * @return */ public static WebElement waitElement(WebDriver driver,int time,By by) { WebElement element=null; WebDriverWait wait = new WebDriverWait(driver, time); try { element = wait.until(new ExpectedCondition<WebElement>() { public WebElement apply(WebDriver driver) { WebElement element = driver.findElement(by); return element; } }); } catch (TimeoutException e) { System.out.println("元素"+by.toString()+" "+time+"S內未能找到"); logger.info("元素未找到"); } return element; } /** * 對外提供智能等待 查找元素的方法,固定的等待超時時間爲5S * @param by * @return */ public static WebElement waitElement(By by) { WebDriver driver= GetDriverUtil.getDriver(); return waitElement(driver, 5, by); /*WebElement element = null; try { element = (new WebDriverWait(driver, 5)).until(new ExpectedCondition<WebElement>() { @Override public WebElement apply(WebDriver driver) { return driver.findElement(by); } }); } catch (Exception e) { System.out.println("元素"+by.toString()+" "+"5S內未能找到"); e.printStackTrace(); } return element;*/ }
上面的ExpectedCondition是咱們本身編寫的,實際上,在selenium的ExpectedConditions類中,已經封裝了各類元素等待條件。有興趣能夠去了解下
能夠去看一下源碼,內部也是使用的匿名內部類new ExpectedCondition{},下面是拿出一個來舉例:
判斷一個元素是否可點擊:
1.該元素在dom中存在
2.該元素可見
3.該元素爲enabled
/** * An expectation for checking an element is visible and enabled such that you can click it. * * @param locator used to find the element * @return the WebElement once it is located and clickable (visible and enabled) */ public static ExpectedCondition<WebElement> elementToBeClickable(final By locator) {
//匿名內部類 return new ExpectedCondition<WebElement>() { @Override public WebElement apply(WebDriver driver) {
//判斷元素是否可見 WebElement element = visibilityOfElementLocated(locator).apply(driver); try {
//若是元素可見而且元素生效的話則返回元素 if (element != null && element.isEnabled()) { return element; } return null; } catch (StaleElementReferenceException e) { return null; } } @Override public String toString() { return "element to be clickable: " + locator; } }; }
上面總結的是元素的等待,自動化測試用,還有:等待頁面加載的超時時間測試。
a.等待頁面加載,設置超時時間。超時以後,再也不等待,直接去定位某元素。(須要執行js腳本)
/**
*等待頁面加載,設置頁面加載的超時時間,若是規定時間內還未加載完成,則中止加載,並定位指定元素
* @param driver
* @param timeout
* @param by
*/
public static void pageLoad(WebDriver driver,int timeout,String url) {
try {
//設置頁面加載超時時間
driver.manage().timeouts().pageLoadTimeout(timeout, TimeUnit.SECONDS);
driver.get(url);
} catch (Exception e) {
((JavascriptExecutor)driver).executeScript("window.stop()");
}
driver.findElement(By.id("user[login]")).sendKeys("feifeifei");
}
b.有時加載頁面超時,須要刷新一次,並輸出頁面的加載狀態。(須要執行js腳本)
/***
* 啓動瀏覽器並打開頁面
*/
public void launchBrowser(String webUrl, int timeOut) {
//getDriver()就是上一篇博客中講的 封裝獲取driver的方法
driver = GetDriverUtil.getDriver();
try {
//最大化瀏覽器窗口(已經封裝成方法)
maxWindow();
//設置等待頁面加載的時間(已經封裝成方法)
waitForPageLoading(timeOut);
//打開瀏覽器指定頁面(已經封裝成方法)
get(webUrl);
} catch (TimeoutException e) {
logger.warn("頁面沒有徹底加載出來,刷新重試");
//刷新頁面
refresh();
//建立js腳本執行器
JavascriptExecutor js = (JavascriptExecutor) driver;
//執行腳本,描述了文檔的加載狀態. 狀態分爲
//loading document 仍在加載
//interactive / 互動 文檔已經完成加載,文檔已被解析,可是諸如圖像,樣式表和框架之類的子資源仍在加載
//complete / 完成 T文檔和全部子資源已完成加載。狀態表示 load 事件即將被觸發。
String status = (String) js.executeScript("return document.readyState");
//將返回的狀態經過日誌打印出來
logger.info("打印狀態:" + status);
}
}
在自動化測試過程當中,還常常遇到異步請求的狀況,以下圖:
當須要進行異步請求元素的定位時,則須要等待異步腳本執行完成並返回結果。這時須要設置異步腳本的超時時間。
/** setScriptTimeout。異步腳本的超時時間。(封裝成方法,方便調用)webdriver能夠異步執行腳本,這個是設置異步執行腳本腳本返回結果的超時時間 */ public void setScriptTimeout(int timeOut) { driver.manage().timeouts().setScriptTimeout(timeOut, TimeUnit.SECONDS); }
以上,詳細介紹了硬性等待、隱式等待、只能等待、頁面加載超時、異步腳本超時的經常使用方法。但願給你們帶來幫助。