Selenium 官網
Selenium WebDriver官網
webdriver實用指南python版本
WebDriver原理
WebDriver是按照Server-Client 的模式設計的。
Server就是 Remote Server,可以是任意的瀏覽器。當我們的腳本啟動瀏覽器后,該瀏覽器就是Remote Server,她的職責就是等待 Client 發送請求并做出響應。
Client 端簡單說就是我們寫的測試腳本。腳本中的一些行為比如打開瀏覽器,跳轉到指定的 URL 等操作就是以 http 請求的方式發送給被測試的瀏覽器,也就是Remote Server。Remote Server接受請求,執行相應操作,并在 Response中返回執行狀態、返回值等信息。
Introducing WebDriver
作者注:WebDriver 可以看作是Selenium-RC替代品。所以現在學習 Selenium 就不需要花時間專注于Selenium-RC了。
Selenium 2.0的主要新特性是WebDriver API的集成。WebDriver旨在提供一個更簡單、更簡潔的編程接口,以解決Selenium-RC API的一些限制。Selenium-WebDriver是為了更好地支持動態web頁面而開發的,頁面的元素在沒有頁面本身被重新加載的情況下可能會發生變化。WebDriver的目標是提供一個設計良好的面向對象的API,為現代高級web應用程序測試問題提供改進的支持。
Selenium RC(Selenium 3.0版本移除了該模塊,以后還是使用 WebDriver 進行腳本的編寫) 由Clent Libraies 和 Selenium Server組成:
Selenium Libraies 用于編寫測試腳本,支持多種不同的主流開發語言,用來控制Selenium Server.
Selenium Server 則負責控制瀏覽器的行為,而Selenium Server 又由三部分組成:
Selenium Core:被Selenium Server 嵌入到瀏覽器頁面中,是一堆的JavaScript 函數的集合,通過這些JavaScript函數來實現對瀏覽器的操作。
Launcher:用于啟動瀏覽器,把Selenium Core加載到瀏覽器頁面當中,并把瀏覽器的代理設置Selenium Server 的Http Proxy。
Http Proxy:Selenium Server的http代理。
??
How Does WebDriver ‘Drive’ the Browser Compared to Selenium-RC?
Selenium-WebDriver使用每個瀏覽器對自動化的本地支持直接調用瀏覽器。這些直接調用是如何生成的,它們支持的特性取決于您使用的瀏覽器。本章稍后將提供關于每個“瀏覽器驅動程序”的信息。
對于那些熟悉Selenium-RC的人來說,這與您所習慣的完全不同。Selenium-RC對每個支持的瀏覽器都使用相同的方法。它在瀏覽器加載時將javascript函數注入瀏覽器,然后使用javascript在瀏覽器中驅動AUT。WebDriver不使用這種技術。同樣,它直接驅動瀏覽器使用內置的支持自動化的瀏覽器。
??
WebDriver and the Selenium-Server
您可能,也可能不需要Selenium服務器,這取決于您打算如何使用Selenium- webdriver。如果您的瀏覽器和測試都運行在同一臺機器上,并且您的測試只使用WebDriver API,那么您就不需要運行selenium服務器;WebDriver將直接運行瀏覽器。
不過,有一些原因可以使用selenium服務器和Selenium-WebDriver。
- 您正在使用Selenium-Grid在多臺機器或虛擬機(vm)上分發測試。
- 您希望連接到具有特定瀏覽器版本的遠程機器,而不是當前機器上的。
- 您沒有使用Java綁定(例如Python、c#或Ruby),并希望使用 HtmlUnit Driver。
Setting Up a Selenium-WebDriver Project
安裝Selenium意味著在開發中建立項目,這樣您就可以使用Selenium編寫程序。如何做到這一點取決于您的編程語言和開發環境。
這里只介紹如何將Selenium添加到Python環境
pip install selenium
或者是:
pip3 install selenium
Pip需要安裝 pip, Pip也依賴于 setuptools。
至于如何將Selenium添加到其他語言環境中,請查閱Selenium WebDriver官網。
至于已經在使用 Selenium1.0的同學們如何轉為使用Selenium WebDriver。請看官網介紹
??
Introducing the Selenium-WebDriver API by Example
WebDriver是一種用于自動化web應用程序測試的工具,特別是用于驗證它們是否按預期工作。它的目標是提供一個友好的API,易于探索和理解,比Selenium-RC (1.0) API更容易使用,這將有助于使您的測試更容易閱讀和維護。它不依賴于任何特定的測試框架,因此它可以在單元測試項目中或從簡單的舊的“main”方法中使用。本節介紹WebDriver的API,并幫助您熟悉它。如果您還沒有建立一個WebDriver項目,那就開始吧。這在前面的小節中描述過,設置了一個Selenium-WebDriver項目。
一旦您的項目建立起來,您可以看到WebDriver就像任何普通的庫一樣:它是完全自包含的,而且您通常不需要記住在使用它之前啟動任何其他進程或運行任何安裝程序,而不是使用Selenium-RC的代理服務器。
注意: 使用 ChromeDriver, Opera Driver, Android Driver 以及 iOS Driver需要額外配置
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
# Create a new instance of the Firefox driver
driver = webdriver.Firefox()
# go to the google home page
driver.get("http://www.google.com")
# the page is ajaxy so the title is originally this:
print driver.title
# find the element that's name attribute is q (the google search box)
inputElement = driver.find_element_by_name("q")
# type in the search
inputElement.send_keys("cheese!")
# submit the form (although google automatically searches now without submitting)
inputElement.submit()
try:
# we have to wait for the page to refresh, the last thing that seems to be updated is the title
WebDriverWait(driver, 10).until(EC.title_contains("cheese!"))
# You should see "cheese! - Google Search"
print driver.title
finally:
driver.quit()
其他腳本語言示例請參考。
??
Selenium-WebDriver API Commands and Operations
??Fetching a Page(獲取某個頁面)
你可能想要做的第一件事是導航到一個頁面。通常的方法是通過調用get:
driver.get("http://www.google.com")
該腳本為 Python 腳本,其他語言腳本請參考。
依賴于幾個因素,包括操作系統/瀏覽器組合,WebDriver可能會等待頁面加載。在某些情況下,WebDriver可以在頁面完成甚至開始加載之前返回控件。為了確保健壯性,您需要等待在頁面中使用 Explicit and Implicit Waits。
解釋:因為網絡環境的因素,每個頁面每次加載的時間會有所不同,如果在某一個頁面加載出來之前,腳本即執行該頁面的某一個元素,則會報錯。所以為了確保頁面已經加載完畢再執行,所以我們會在必要的時候使用 wait 命令。
??Locating UI Elements (WebElements)
在WebDriver中定位元素可以在WebDriver實例本身或WebElement上完成。每個語言綁定公開一個 “Find Element” and “Find Elements” 方法。前者返回與查詢匹配的WebElement對象,如果不能找到該元素,則拋出異常。后者返回一個WebElements列表,如果沒有DOM元素匹配查詢,則可能為空。
“Find”方法采用名為“By”的定位器或查詢對象。下面列出了“策略”。
作者注:DOM屬性
DOM 是 W3C(萬維網聯盟)的標準。
屬性是節點(HTML 元素)的值,您能夠獲取或設置。
??By ID
這是定位一個元素最有效的方法。UI開發人員所犯的常見錯誤是在頁面上有非惟一id,或者自動生成id,這兩個都應該避免。html元素上的類比自動生成的id更合適。
如果待測元素的源碼如下所示,我們該如何定位呢:
<div id="coolestWidgetEvah">...</div>
解釋:此處我們假設該元素是一個按鈕。該元素的 id 即為coolestWidgetEvah。就可以通過 id 定位到該元素。除非某個元素沒有 id 這個屬性,一般我們都使用 id 定位元素。
以下使用 id定位 元素為 Python 腳本示例:
element = driver.find_element_by_id("coolestWidgetEvah")
或者
from selenium.webdriver.common.by import By
element = driver.find_element(by=By.ID, value="coolestWidgetEvah")
解釋:通過這兩個方法均可以定位到該按鈕,并將該方法返回的值賦值給變量 element,以便進行其他操作。
其他語言腳本示例請參考
??By Class Name
本例中的“類”是指DOM元素上的屬性。通常在實際使用中,有許多具有相同類名的DOM元素,因此,查找第一個元素時,找到多個元素成為更實際的選擇。
類似下面的待測 web 頁面源碼,我們如何使用該方法定位元素呢:
<div class="cheese"><span>Cheddar</span></div><div class="cheese"><span>Gouda</span></div>
解釋:該元素的 class(類)即 cheese。
Python 腳本如下:
cheeses = driver.find_elements_by_class_name("cheese")
或者
from selenium.webdriver.common.by import By
cheeses = driver.find_elements(By.CLASS_NAME, "cheese")
其他語言腳本請參考。
??By Tag Name
元素的DOM標記名。
類似下面的待測 web 頁面源碼,我們如何使用該方法定位元素呢:
<iframe src="..."></iframe>
Python 示例:
frame = driver.find_element_by_tag_name("iframe")
或者
from selenium.webdriver.common.by import By
frame = driver.find_element(By.TAG_NAME, "iframe")
其他腳本語言示例請參考。
通過 tag 識別某個元素的概率很低,例如我們打開任意一個頁面,查看前端都會發現大量的<div>、<input>、<a>等等 tag。除非一個頁面只有這一個沒有重復的 tag,比如上述示例,<iframe>就是很少用的一個 tag,如果一個頁面中只有這么一個<iframe>tag 那么就可以用 tag 定位。
??By Name
找到具有匹配名稱屬性的輸入元素。
類似下面的待測 web 頁面源碼,我們如何使用該方法定位元素呢:
<input name="cheese" type="text"/>
以下為 Python 示例:
cheese = driver.find_element_by_name("cheese")
或者
from selenium.webdriver.common.by import By
cheese = driver.find_element(By.NAME, "cheese")
其他腳本語言示例請參考。
??By Link Text
找到與可見文本匹配的鏈接元素。
類似下面的待測 web 頁面源碼,我們如何使用該方法定位元素呢:
<a >cheese</a>>
以下為 Python 示例:
cheese = driver.find_element_by_link_text("cheese")
或者
from selenium.webdriver.common.by import By
cheese = driver.find_element(By.LINK_TEXT, "cheese")
比如百度主頁頂部的一行鏈接,如圖:
如果想要點擊“新聞”這個鏈接,那么就使用這個定位方法。
其他腳本語言示例請參考。
??By Partial Link Text
找到帶有部分匹配可見文本的鏈接元素。
類似下面的待測 web 頁面源碼,我們如何使用該方法定位元素呢:
<a >search for cheese</a>>
以下為 Python 示例:
cheese = driver.find_element_by_partial_link_text("cheese")
或者
from selenium.webdriver.common.by import By
cheese = driver.find_element(By.PARTIAL_LINK_TEXT, "cheese")
比如百度主頁底部有一個比較長的鏈接,如圖:
這個鏈接的完整文本是“京公網安備11000002000001號”,我們使用部分文本,比如“京公網”就可以唯一確定是這個鏈接。此時就可以使用該定位方法。
??By CSS
顧名思義,它是css的定位策略。默認情況下使用本機瀏覽器支持,所以請參考w3c css selectors,以獲得一般可用的css選擇器列表。如果瀏覽器沒有對css查詢的本機支持,則使用 Sizzle。IE6、7和FF3.0目前使用Sizzle作為css查詢引擎。
要注意的是,并非所有的瀏覽器都是相同的,有些css可能在一個版本中工作,但在另一個版本中可能無效。
比如下面查找“cheese”這個元素:
<div id="food"><span class="dairy">milk</span><span class="dairy aged">cheese</span></div>
python腳本示例:
cheese = driver.find_element_by_css_selector("#food span.dairy.aged")
解釋一下這個定位方法:
- #表示通過 id 屬性定位元素,因為 food 是一個 id 屬性值,所以前面加一個#號;
- 通過標簽名定位元素前面不加任何符號標識,直接使用標簽名即可,因為 span 是一個標簽名,所以前面什么都不加;
- . 表示通過 class 屬性定位元素,因為 dairy 是一個 class 屬性值,所以前面加一個.號。
這個腳本用的是多種方式的組合。通過一級級標簽進行最終的定位。我們還以百度主頁為例進行舉例說明。
比如通過 class 屬性定位到輸入框 這個元素:
find_element_by_css_selector(".s_ipt")
比如通過 id 屬性定位到輸入框這個元素:
find_element_by_css_selector("#kw")
比如通過標簽名定位(當然這里不適用,標簽名<input>不唯一):
find_element_by_css_selector("input")
通過組合定位就是:
find_element_by_css_selector("input#kw")
注意:這里 class 和 id 兩個屬性是同一級標簽下的屬性,只使用一個。
為了更精確的定位,我們還可以使用剛精確的定位方式:
find_element_by_css_selector("div span input#kw")
這種組合方式還有很多,再舉一例:
browser.find_element_by_css_selector("form.fm span.bg.s_ipt_wr.quickdelete-wrap input.s_ipt").send_keys(u"簡書")
注意: 最后在輸入框輸入漢字的時候在漢字前加了一個字母 u,如果不加則會造成漢字無法識別的錯誤
或者
from selenium.webdriver.common.by import By
cheese = driver.find_element(By.CSS_SELECTOR, "#food span.dairy.aged")
??By XPath
在高層次上,WebDriver盡可能使用瀏覽器的本地XPath功能。在那些沒有本地XPath支持的瀏覽器上,我們提供了自己的實現。這可能導致一些意外的行為,除非您意識到不同的XPath引擎之間的差異。(總之一句話,不到別無選擇,不推薦使用 XPath 定位)。
Driver | Tag and Attribute Name | Attribute Values | Native XPath Support |
---|---|---|---|
HtmlUnit Driver | Lower-cased | As they appear in the HTML | Yes |
Internet Explorer Driver | Lower-cased | As they appear in the HTML | No |
Firefox Driver | Case insensitive | As they appear in the HTML | Yes |
這是一個有點抽象的東西,所以對于下面這段HTML:
<input type="text" name="example" />
<INPUT type="text" name="other" />
python 腳本示例:
inputs = driver.find_elements_by_xpath("http://input")
或者
from selenium.webdriver.common.by import By
inputs = driver.find_elements(By.XPATH, "http://input")
將會找到以下的匹配數:
XPath expression | HtmlUnit Driver | Firefox Driver | Internet Explorer Driver |
---|---|---|---|
//input | 1 (“example”) | 2 | 2 |
//INPUT | 0 | 2 | 0 |
有時,HTML元素不需要顯式地聲明屬性,因為它們將默認為已知值。例如,“input”標簽不需要“type”屬性,因為它默認為“text”。在WebDriver中使用xpath時的經驗法則是,您不應該期望能夠與這些隱式屬性相匹配。
這里介紹一下“絕對路徑定位”方法,這個方法在定位元素走投無路的時候或許能幫助你。我們還是以百度首頁的輸入框為例,如下圖:
如果這個輸入框元素的屬性沒有 id,沒有 class,沒有name。咋辦,使用 tag 定位?你可以看到這個頁面不止一個<input>,不具有唯一性,所以無法使用 tag 定位。此時就可以使用絕對路徑定位。腳本如下:
find_element_by_xpath("/html/body/div/div[1]/div/div/div/form/span/input")
看起來就有點暈,我來解釋一下。
這里是通過標簽定位,必須要從<html>開始。<html>的下一級標簽有<head>和<body>,這兩個標簽是平級的,沒有父子之分,因為我們要定位的元素在標簽<body>下,所以<html>之后是<body>。<body>之后又有兩個平級標簽<script>和<div>,我們選擇<div>。但是這個<div>標簽之后有多個平級標簽<div>,上面截圖沒有體現,看下圖:
。
這個標簽下有很多平級標簽均未<div>,而我們要找的是第一個<div>,所以是<div>[1]。以此類推,直達定位到目標元素。
注意:這種定位方法不到萬不得已不使用,因為一旦頁面有一點改動,定位就可能會出錯。
??Using JavaScript
您可以執行任意的javascript來找到一個元素,只要返回一個DOM元素,它就會自動轉換成一個WebElement對象。
在具有jQuery的頁面上的簡單示例:
java示例:
WebElement element = (WebElement) ((JavascriptExecutor)driver).executeScript("return $('.cheese')[0]");
python 示例:
element = driver.execute_script("return $('.cheese')[0]")
查找頁面上每個標簽的所有輸入元素:
java示例:
List<WebElement> labels = driver.findElements(By.tagName("label"));
List<WebElement> inputs = (List<WebElement>) ((JavascriptExecutor)driver).executeScript(
"var labels = arguments[0], inputs = []; for (var i=0; i < labels.length; i++){" +
"inputs.push(document.getElementById(labels[i].getAttribute('for'))); } return inputs;", labels);
python 示例:
labels = driver.find_elements_by_tag_name("label")
inputs = driver.execute_script(
"var labels = arguments[0], inputs = []; for (var i=0; i < labels.length; i++){" +
"inputs.push(document.getElementById(labels[i].getAttribute('for'))); } return inputs;", labels)
??Getting text values
人們通常希望檢索元素中包含的innerText值。這會返回單個字符串值。注意,這只會返回頁面上顯示的可見文本。
python 示例:
element = driver.find_element_by_id("element_id")
element.text
??User Input - Filling In Forms
我們已經看到了如何將文本輸入到文本區域或文本字段中,但是其他元素又如何呢?您可以“切換”復選框的狀態,您可以使用“click”設置一些類似于選擇的選項標記。處理選擇標簽并不是很糟糕:
Python 腳本示例:
select = driver.find_element_by_tag_name("select")
allOptions = select.find_elements_by_tag_name("option")
for option in allOptions:
print "Value is: " + option.get_attribute("value")
option.click()
這將在頁面上找到第一個“SELECT”元素,然后依次遍歷每個選項,打印出它們的值,然后依次選擇它們。您會注意到,這并不是處理SELECT元素的最有效方法。WebDriver的支持類包括一個名為“Select”的類,它提供了與這些類交互的有用方法。
python
# available since 2.12
from selenium.webdriver.support.ui import Select
select = Select(driver.find_element_by_tag_name("select"))
select.deselect_all()
select.select_by_visible_text("Edam")
這將從頁面上的第一個SELECT中取消所有選項,然后選擇帶有“Edam”的顯示文本的選項。
填寫完表單后,您可能需要提交它。一種方法是找到“提交”按鈕并點擊它:
python
driver.find_element_by_id("submit").click()
Alternatively, WebDriver has the convenience method “submit” on every element. If you call this on an element within a form, WebDriver will walk up the DOM until it finds the enclosing form and then calls submit on that. If the element isn’t in a form, then the NoSuchElementException will be thrown:
python
element.submit()
??Moving Between Windows and Frames
一些web應用程序有許多框架或多個窗口。WebDriver支持使用“切換”方法在指定的窗口之間移動:
driver.switch_to.window("windowName")
所有對驅動程序的調用將被解釋為指向特定的窗口。但是你怎么知道窗戶的名字呢?看一下打開的javascript或鏈接:
<a href="somewhere.html" target="windowName">Click here to open a new window</a>
或者,您可以將“窗口句柄”傳遞給“切換().window()”方法。知道了這一點,就可以遍歷每個打開的窗口:
python
for handle in driver.window_handles:
driver.switch_to.window(handle)
作者注:HANDLE(句柄)是Windows操作系統中的一個概念。在Windows程序中,有各種各樣的資源(窗口、圖標、光標等),系統在創建這些資源時會為它們分配內存,并返回標示這些資源的標示號,即句柄。(摘自互動百科)
??Popup Dialogs
從Selenium 2.0 beta 1開始,構建了支持處理彈出對話框的支持。在您觸發一個打開彈出窗口的操作之后,您可以通過以下方式訪問警報:
python
alert = driver.switch_to.alert
# usage: alert.dismiss(), etc.
這將返回當前打開的警告對象。通過這個對象,您現在可以接受、解散、讀取它的內容,甚至可以鍵入一個提示符。這個接口在警報、確認和提示上同樣有效。更多信息請參考JavaDocs或RubyDocs。
??Navigation: History and Location
早些時候,我們使用“get”命令(driver.get(“http://www.example.com”)或driver.Url=“http://www.example.com”在c#中導航到一個頁面。如您所見,WebDriver有許多較小的、面向任務的接口,導航是一項有用的任務。因為加載頁面是一個基本的要求,所以在主WebDriver接口上執行這個操作的方法,但是它只是一個同義詞:
python
driver.get("http://www.example.com") # python doesn't have driver.navigate
重申:“導航(). To()”和“get()”做完全相同的事情。一個人比另一個更容易打字!
“導航”界面也暴露了在瀏覽器的歷史中來回移動的能力:
python
driver.forward()
driver.back()
請注意,此功能完全依賴于底層瀏覽器。如果你習慣了一個瀏覽器的行為,那么你調用這些方法時可能會發生意想不到的事情。
??Cookies
在我們開始下一步內容之前,您可能會對如何使用cookie感興趣。首先,您需要在cookie將有效的域上。如果你想在開始與網站交互之前預設cookie,而你的主頁是大的/需要一段時間來加載另一種選擇,那就是在網站上找到一個較小的頁面(通常是404頁面很小,例如http://example.com/some404page)。
Python
# Go to the correct domain
driver.get("http://www.example.com")
# Now set the cookie. Here's one for the entire domain
# the cookie name here is 'key' and its value is 'value'
driver.add_cookie({'name':'key', 'value':'value', 'path':'/'})
# additional keys that can be passed in are:
# 'domain' -> String,
# 'secure' -> Boolean,
# 'expiry' -> Milliseconds since the Epoch it should expire.
# And now output all the available cookies for the current URL
for cookie in driver.get_cookies():
print "%s -> %s" % (cookie['name'], cookie['value'])
# You can delete cookies in 2 ways
# By name
driver.delete_cookie("CookieName")
# Or all of them
driver.delete_all_cookies()
??Changing the User Agent
這對于Firefox Driver來說很簡單:
python
profile = webdriver.FirefoxProfile()
profile.set_preference("general.useragent.override", "some UA string")
driver = webdriver.Firefox(profile)
??Drag And Drop
這里有一個使用action類來執行拖放操作的示例。必須啟用本地事件。
python
from selenium.webdriver.common.action_chains import ActionChains
element = driver.find_element_by_name("source")
target = driver.find_element_by_name("target")
ActionChains(driver).drag_and_drop(element, target).perform()
??
Driver Specifics and Tradeoffs
Selenium-WebDriver’s Drivers
WebDriver是測試應該編寫的關鍵接口的名稱,但是有幾個實現。這些包括:
??HtmlUnit Driver
這是目前最快速、最輕量級的WebDriver實現。顧名思義,這是基于HtmlUnit的。HtmlUnit是一個沒有GUI的基于java的WebBrowser實現。對于任何語言綁定(除了java), Selenium服務器都需要使用這個驅動程序。
????Usage
python
driver = webdriver.Remote("http://localhost:4444/wd/hub", webdriver.DesiredCapabilities.HTMLUNIT.copy())
????Pros
- 最快的實現WebDriver
- 純Java解決方案,因此它是平臺無關的。
- 支持JavaScript.
????Cons
- 模擬其他瀏覽器的JavaScript行為(見下面)
????JavaScript in the HtmlUnit Driver
沒有一個流行的瀏覽器使用HtmlUnit (Rhino)使用的JavaScript引擎。如果您使用HtmlUnit測試JavaScript,結果可能與那些瀏覽器有很大不同。
當我們說“JavaScript”時,實際上是指“JavaScript和DOM”。雖然DOM是由W3C定義的,但是每個瀏覽器都有自己的特性和在DOM的實現上的差異,以及JavaScript如何與DOM交互。HtmlUnit有一個令人印象深刻的完整實現使用JavaScript DOM和具有良好的支持,但它是沒有不同于其他任何瀏覽器:它有自己的怪癖和差異來自W3C標準和主流瀏覽器的DOM實現,盡管其模仿其他瀏覽器的能力。
有了WebDriver,我們必須做出選擇;我們是否啟用了HtmlUnit的JavaScript功能,并運行那些只出現在那里的問題的團隊的風險,或者我們是否禁用了JavaScript,知道有越來越多的站點依賴于JavaScript?我們采用了保守的方法,默認情況下在使用HtmlUnit時禁用了支持。隨著WebDriver和HtmlUnit的每個版本的發布,我們重新評估這個決定:我們希望在HtmlUnit上默認啟用JavaScript。
????Enabling JavaScript
If you can’t wait, enabling JavaScript support is very easy:
Python
driver = webdriver.Remote("http://localhost:4444/wd/hub", webdriver.DesiredCapabilities.HTMLUNITWITHJS)
這將導致HtmlUnit驅動程序在默認情況下模擬Firefox 3.6的JavaScript處理。
??Firefox Driver
使用Firefox插件控制 Firefox瀏覽器。使用的Firefox配置文件從安裝在機器上的內容剝離出來,只包含了Selenium WebDriver。xpi(插件)。默認情況下,一些設置也會發生變化(參見源代碼,看看哪些是Firefox驅動程序),Firefox驅動程序可以在Windows、Mac和Linux上進行測試。目前版本3.6, 10, latest - 1, latest。
????Usage
python
driver = webdriver.Firefox()
????Pros
- 在真正的瀏覽器中運行并支持JavaScript。
- 比Internet Explorer Driver更快。
????Cons
- Slower than the HtmlUnit Driver
????修改Firefox配置文件
假設您想修改用戶代理字符串(如上所示),但是您已經得到了一個包含幾十個有用擴展的Firefox配置文件。獲取這個概要文件有兩種方法。假設該配置文件是使用Firefox的配置文件管理器(Firefox -ProfileManager)創建的:
java
ProfilesIni allProfiles = new ProfilesIni();
FirefoxProfile profile = allProfiles.getProfile("WebDriver");
profile.setPreferences("foo.bar", 23);
WebDriver driver = new FirefoxDriver(profile);
當我們在Firefox Driver中開發特性時,我們就暴露了使用它們的能力。例如,在我們感覺本地事件在Firefox中是穩定的Linux,在默認情況下它們是禁用的。使他們:
python
profile = webdriver.FirefoxProfile()
profile.native_events_enabled = True
driver = webdriver.Firefox(profile)
????Info
請參閱wiki頁面中的Firefox部分,了解最新的信息。
??Internet Explorer Driver
InternetExplorerDriver是一個獨立的服務器,它實現了WebDriver的有線協議。這個驅動程序已經測試了ie7、8、9、10和11,并在Vista、Windows 7、Windows 8和Windows 8.1的適當組合上進行了測試。截至2014年4月15日,IE 6不再受支持。
驅動程序支持運行32位和64位版本的瀏覽器。如何確定在啟動瀏覽器時使用哪個“bit-ness”取決于IEDriverServer的哪個版本。exe。如果是32位版本的IEDriverServer。exe啟動后,IE的32位版本將啟動。同樣,如果IEDriverServer的64位版本。exe啟動,將啟動64位版本IE。
????Usage
Python
driver = webdriver.Ie()
????Pros(優點)
- 在真正的瀏覽器中運行并支持Javascript。
????Cons(缺點)
- 很明顯,InternetExplorerDriver只會在Windows上運行!
- 比較慢(雖然還是很時髦!)
????Info
查看wiki頁面的Internet Explorer部分 ,了解最新的信息。請特別注意所需的配置部分。
??
??ChromeDriver
ChromeDriver由Chromium項目維護/支持。WebDriver通過chromedriver二進制文件(在chromium項目的下載頁面上找到)與Chrome合作。你需要安裝chromedriver和chrome瀏覽器的版本。chromedriver需要放在系統的路徑上,以便WebDriver自動發現它。chromedriver在默認安裝路徑中發現了Chrome瀏覽器本身。這些都可以被環境變量覆蓋。更多信息請參考 the wiki(維基百科)。
????Usage
Python
driver = webdriver.Chrome()
????Pros(優點)
在真正的瀏覽器中運行并支持JavaScript。
因為Chrome是一個基于webkit的瀏覽器,ChromeDriver可以讓你驗證你的網站在Safari中運行。注意,由于Chrome使用的是自己的V8 JavaScript引擎而不是Safari的Nitro引擎,JavaScript的執行可能會有所不同。
????Cons(缺點)
- Slower than the HtmlUnit Driver
??
????Info
See our wiki,了解最新的信息。更多信息也可以在 downloads page
找到。
??
????Getting running with ChromeDriver
下載ChromeDriver可執行文件,并遵循 wiki page上的其他說明。
??
??Opera Driver
See the Opera Driver wiki article in the Selenium Wiki for information on using the Opera Driver.
??
??iOS Driver
See either the ios-driver or appium projects.
??
??Android Driver
See the Selendroid project
??
Alternative Back-Ends: Mixing WebDriver and RC Technologies
??WebDriver-Backed Selenium-RC
WebDriver的Java版本提供了Selenium-RC API的實現。這意味著您可以使用Selenium-RC API使用底層的WebDriver技術。這主要是為向后兼容性提供的。它允許使用Selenium-RC API的現有測試套件在覆蓋下使用WebDriver。它提供了幫助簡化遷移到Selenium-WebDriver的路徑。同樣,這允許在相同的測試代碼中同時使用兩個api。
Selenium-WebDriver是這樣使用的:
java
// You may use any WebDriver implementation. Firefox is used here as an example
WebDriver driver = new FirefoxDriver();
// A "base url", used by selenium to resolve relative URLs
String baseUrl = "http://www.google.com";
// Create the Selenium implementation
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
// Perform actions with selenium
selenium.open("http://www.google.com");
selenium.type("name=q", "cheese");
selenium.click("name=btnG");
// Get the underlying WebDriver implementation back. This will refer to the
// same WebDriver instance as the "driver" variable above.
WebDriver driverInstance = ((WebDriverBackedSelenium) selenium).getWrappedDriver();
//Finally, close the browser. Call stop on the WebDriverBackedSelenium instance
//instead of calling driver.quit(). Otherwise, the JVM will continue running after
//the browser has been closed.
selenium.stop();
????優點(Pros)
- 允許WebDriver和Selenium api共存。
- 提供從Selenium RC API到WebDriver的管理遷移的簡單機制。
- 不需要運行獨立的Selenium RC服務器嗎?
????缺點(Cons)
- 不能實現每個方法
- 更高級的Selenium使用(使用“browserbot”或來自Selenium Core的其他內置JavaScript方法)可能不起作用。
- 由于底層實現差異,一些方法可能會比較慢。
??Backing WebDriver with Selenium
WebDriver不像Selenium RC那樣支持很多瀏覽器,所以為了在使用WebDriver API時提供支持,您可以使用SeleneseCommandExecutor。
以這種方式支持Safari,并使用以下代碼(確保禁用彈出式阻塞):
java(官方文檔只提供了 JAVA 示例):
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("safari");
CommandExecutor executor = new SeleneseCommandExecutor(new URL("http://localhost:4444/"), new URL("http://www.google.com/"), capabilities);
WebDriver driver = new RemoteWebDriver(executor, capabilities);
目前,這種方法存在一些主要的局限性,尤其是findElements不像預期的那樣工作。另外,由于我們使用Selenium Core來驅動瀏覽器,所以您受到JavaScript sandbox的限制。
??
運行獨立的Selenium服務器,用于遠程驅動程序(Running Standalone Selenium Server for use with RemoteDrivers)
從Selenium的下載頁面下載selenium-server-standalone-<version>。jar和可選IEDriverServer。如果您計劃使用Chrome,請從 Google Code下載。
打開IEDriverServer和/或chromedriver,并將它們放在$PATH / %PATH%上的目錄中—Selenium服務器應該能夠處理對IE / Chrome的請求,而無需進行額外的修改。
在命令行上啟動服務器
java -jar <path_to>/selenium-server-standalone-<version>.jar
如果您想要使用本機事件功能,請在命令行上使用該選項指示此功能
-Dwebdriver.enable.native.events=1
對于其他命令行選項,執行
java -jar <path_to>/selenium-server-standalone-<version>.jar -help
為了正常運行,應該允許以下端口進入TCP連接:4444、7054-5(或者是您計劃運行的并發實例數量的兩倍)。在Windows下,您可能還需要打開應用程序。
Additional Resources
你可以在 WebDriver’s wiki中找到更多的WebDriver資源。
當然,不要猶豫,在任何Selenium主題上進行internet搜索,包括Selenium- webdriver的驅動程序。有很多關于Selenium的博客,以及許多用戶論壇上的帖子。另外,Selenium User’s Group是一個很好的資源。
http://groups.google.com/group/selenium-users。
Next Steps
這一章簡單地介紹了WebDriver及其一些關鍵功能。一旦熟悉了Selenium-WebDriver API,您就會想要學習如何構建可維護性、可擴展性和降低脆弱性的測試套件。大多數Selenium專家現在建議的方法是使用頁面對象設計模式(Page Object Design Pattern)和可能的頁面工廠(Page Factory)來設計測試代碼。通過在Java和c#中提供一個PageFactory類,Selenium-WebDriver提供了支持。在 next chapter中,我們將介紹這一主題,以及其他高級主題。另外,對于該技術的高級描述,您可能需要查看 Test Design Considerations chapter。這兩章都介紹了通過使測試代碼更模塊化編寫更易于維護的測試的技術。
Next topic