webdriver(python)學習筆記一

最近有python開發的項目,也正打算要學習自動化與python語言。所以想經過學習python版本的webdriver來一同窗習。javascript

學習過程當中參考資料有乙醇的博客:https://github.com/easonhan007/webdriver_guide/blob/master/README.md,蟲師的博客:http://www.cnblogs.com/fnng/css

以及python的官方文檔:http://docs.seleniumhq.org/docs/03_webdriver.jsp#firefox-driverhtml

 

 

selenium webdriver的API介紹java


webdriver的是一個Web應用程序測試自動化工具,用來驗證程序是否如預期的那樣執行。它的目的是提供一個友好的API,比selenium RC(1.0)API更容易使用,這將有助於使你的測試腳本更容易閱讀和維護。它不依賴於任何特定的測試框架,因此它能夠用於單元測試或者一個老式的「main」方法中。本節介紹webdriver的API,下面讓咱們來幫助你熟悉它。python

 

若是你已經設置了項目,你就會發現,webdriver的做用跟其它庫同樣:它是徹底獨立的,你一般在使用以前不須要啓動任何額外的進程,或者運行任何安裝程序,若是使用Selenium-RC則要到代理服務器。 git

 

注:須要額外的驅動來使腳本在不一樣環境下運行:Chrome Driver, Opera Driver, Android Driver andiPhone Driver。默認是支持的Firefox Driver。github

 

如今咱們經過一個代碼來了解其機制。代碼實現:打開瀏覽器,輸入谷歌網頁,並在搜索框內輸入「Cheese」 點擊搜索,最後關閉瀏覽器。web

 

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")

# 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()

# the page is ajaxy so the title is originally this:
print driver.title

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()

 

 

 

在下面的章節中,您將瞭解更多有關如何使用webdriver的東西,如如何使用瀏覽器的前進和後退功能(這在selenium 1.0中不能被很好的支持);以及如何使用框架和窗口測試網站。咱們將會提供了更深刻的討論和範例。 ajax

 

Selenium webdriver的API命令和操做chrome

 


 

取回頁面

 

你可能使用webdriver想要作的第一件事是導航到一個頁面,經過「get」能夠輕鬆的作到之一點

 

driver.get(http://www.google.com

 

webdriver的運行依賴於幾個因素:包括操做系統/瀏覽器的組合,有時可能須要等待頁面加載。webdriver的在某些狀況下,可能須要控制返回頁面的開始與加載時間。爲了確保腳本的穩定性,須要等待的元素(S)在頁面中存在的 顯性和隱性的等待

 

 

 

定位UI元素(WebElements)

 


參考:http://www.cnblogs.com/fnng/archive/2012/01/12/2321117.html

 

自動化要想模擬用戶(人)的行爲操做,首先須要識別並定位UI上的元素,每一個元素都有特定屬性,webdriver就是經過識別元素的屬性來定位元素。

 

咱們能夠經過下面的一些屬性或方法來定定位元素: 

 

ID 

 


 

這是最有效和最優選的方式來定位一個元素。常見的陷阱,開發人員能夠爲元素設置非惟一的ID ,或經過自動生成ID ,應該避免這種狀況。

 

如何經過ID的方式定位一個元素,看下面這樣的例子: 

 

<div id="coolestWidgetEvah">...</div>

element = driver.find_element_by_id("coolestWidgetEvah")

or

from selenium.webdriver.common.by import By
element = driver.find_element(by=By.ID, value="coolestWidgetEvah")

 

 

 

By class name

 


 

「class 」是指DOM元素的屬性。但在實際使用中有不少相同類名的DOM元素,在發現多個相同類名的元素時,程序會默認選擇最早找到的第一個元素。

 

如何經過類名找到一個元素,看下面的例子:

 

<div class="cheese">
<span>Cheddar</span>
</div>
<div class="cheese">
<span>Gouda</span>
</div>

cheeses = driver.find_elements_by_class_name("cheese")

or

from selenium.webdriver.common.by import By
cheeses = driver.find_elements(By.CLASS_NAME, "cheese")

 

 

By tag name 

 


 

DOM標籤名稱的元素。

 

具體方式以下面的例子:

 

<iframe src="..."></iframe>
frame = driver.find_element_by_tag_name("iframe")

or

from selenium.webdriver.common.by import By
frame = driver.find_element(By.TAG_NAME, "iframe")
By name

 

 

查找並匹配元素的name屬性

 


 

具體方式以下面的例子:

 

 
<input name="cheese" type="text"/>

cheese = driver.find_element_by_name("cheese")

or

from selenium.webdriver.common.by import By

cheese = driver.find_element(By.NAME, "cheese")

By link text

 

 

 

經過連接文本找到元素匹配

 


例子以下:

 

<a href="http://www.google.com/search?q=cheese">cheese</a>>
cheese = driver.find_element_by_link_text("cheese")

or
 
from selenium.webdriver.common.by import By
cheese = driver.find_element(By.LINK_TEXT, "cheese") 
By Partial Link Text

 

 

 

 

經過查找部分連接文件匹配元素

 


 

例子以下:

 

<a href="http://www.google.com/search?q=cheese">search for cheese</a>>
cheese = driver.find_element_by_partial_link_text("cheese")

or

from selenium.webdriver.common.by import By
cheese = driver.find_element(By.PARTIAL_LINK_TEXT, "cheese")

 

 

 

By CSS 

 


 

 經過CSS的定位策略。默認狀況下本機瀏覽器支持CSS定位,因此,請參考W3C CSS選擇器

 

<http://www.w3.org/TR/CSS/#selectors> 顯示通常可用的CSS選擇器的列表。若是瀏覽器沒有原生支持CSS查詢,可使用Sizzle(Sizzle是一個純javascript CSS選擇器引擎)。目前,IE 6,7和FF3.0使用Sizzle的CSS查詢引擎。

 

注意:不是全部瀏覽器對CSS的支持都是同樣的,可能在一個瀏覽器中運行良好,切換到另外一個瀏覽器則否則。

 

具體用法以下:

 

<div id="food">

<span class="dairy">milk</span>

<span class="dairy aged">cheese</span>

</div>

cheese = driver.find_element_by_css_selector("#food span.dairy.aged")


or

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支持

HtmlUnit Driver

小寫

當他們出如今HTML

Internet Explorer Driver

小寫

當他們出如今HTML

沒有

Firefox Driver

不區分大小寫

當他們出如今HTML

 

 

這點抽象,對於下面這段HTML 代碼來講:

 

<input type="text" name="example" />
<INPUT type="text" name="other" />
inputs = driver.find_elements_by_xpath("//input")


or


from selenium.webdriver.common.by import By
inputs = driver.find_elements(By.XPATH, "//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時,你不該該指望可以對這些隱含的屬性相匹配。

 

 

使用JavaScript 

 


 

你能夠執行任意javascript來找到一個元素,只要你返回一個DOM元素,它將自動轉換爲一個WebElement對象。

 

簡單的例子,在頁面上加載了jQuery:

 

element = driver.execute_script("return $('.cheese')[0]")

 

在頁面上的每個標籤查找全部輸入元素:

 

 
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)

 

 

 

用戶輸入-填寫表單

 


 

咱們已經看到了如何將文字輸入到一個文本或文本字段,但其餘元素?您能夠「切換」複選框的狀態,你可使用「點擊」設置相似選擇的選項標記。處理SELECT標籤是否是太糟糕:

 

 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」,它提供了一些有用的方法,來處理這些交互。

 

# 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")

  

 

從頁面上第一個選擇開始取消全部選項,從第一個選擇頁面上的全部選項,而後選擇顯示的文本與「Edam」 的選項。

 

當你完成填寫表格,你可能要提交。咱們須要找到「提交」按鈕,而後單擊它:

 

driver.find_element_by_id("submit").click()

 

 

 

另外,有方便的方法能夠在webdriver的每一個元素上的「提交」。若是調用此表單內的元素,webdriver經過的DOM按順序找到封閉的形式,而後調用該提交。若是該元素不是一種形式,那麼會拋出NoSuchElementException異常:

 

element.submit()

 

 

 

移動Windows和框架(Frames)

 


 

 

一些web應用程序有許多框架或多個窗口。經過webdriver的「switchTo」方法能夠對他們呢進行移動操做。

 

driver.switch_to_window("windowName")

 

 

調用驅動程序如今解釋爲被定向到特定的窗口。可是如何知道窗口的名字?以JavaScript或連接的方式打開它看看:

 

<a href="somewhere.html" target="windowName">Click here to open a new window</a>

 

 

另外,你也能夠經過「window handle」的「switchTo().window()」方法。認識到這一點,那麼就能夠遍歷全部打開的窗口,像這樣:

 

for handle in driver.window_handles:

    driver.switch_to_window(handle)

 

 

 

還能夠切換從frames到frames(或到iframe中):

 

driver.switch_to_frame("frameName")

 

 

訪問子frames由一個圓點分隔的路徑,而且能夠經過其索引指定frames。是:

 

driver.switch_to_frame("frameName.0.child")

 

would go to the frame named 「child」 of the first subframe of the frame called 「frameName」.All frames are evaluated as if from *top*. -----實在不知道這個怎麼翻譯

 

 

 

 

彈出對話框


Selenium 2.0測試版一開始,內置有處理彈出對話框支持。當你觸發一個動做,打開一個彈出框,您將獲得如下提醒:

 

alert = driver.switch_to_alert()

# usage: alert.dismiss(), etc.

 

這將返回當前打開的警報對象。有了這個對象,你如今能夠接受,拒絕,讀取其內容,甚至類型會獲得一個提示。這個接口一樣適用警告,確認和提示。參考到的JavaDoc 或RubyDocs的的更多信息。

 

 

 

 

 

導航:歷史和位置

 


 

此前,咱們介紹了webdriver的導航使用「get」命令

 

(driver.get(「http://www.example.com」)),咱們在有些狀況下是要用到導航欄前進和頭退功能:

 

driver.get("http://www.example.com")  # python doesn't have driver.navigate

 

 

重申:「navigate().to()」 和 「get()」  的效果是同樣的。一個只是不少比其餘更容易輸入!

 

你能夠隨意的使用瀏覽器歷史記錄中後退和前進功能:

 

driver.forward()

driver.back()

 

 請注意,此功能徹底依賴於底層瀏覽器。當你調用這些方法時,在不一樣的瀏覽器下可能會發生意想不到的事情

 

 

 

 

 

Cookies

 


 

 

你可能會很是感興趣瞭解如何使用Cookie。首先,你須要知道cookie有效期。若是您想先預設的cookie,而後再開始與網站進行交互,你的主頁很大/且須要一段時間來加載,一個辦法是找到一個更小的網頁來代替,一般404頁小(http://example.com/some404page

 

複製代碼
#轉到正確的域

driver.get("http://www.example.com")

 

#如今在這裏的整個域設置的cookie,

#這裏的cookie的名稱是'key',它的值是'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.


# 如今的輸出當前URL的全部可用的cookies

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()
複製代碼

 

 

更改用戶代理

 


 

這是很容易與Firefox的驅動程序

 

 

拖放


 

 

下面是一個例子使用執行拖放動做類。本地事件事件須要被激活。

 

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()

 

驅動程序的細節和權衡

 

 

Selenium webdriver的驅動程序

 


 參考:http://www.cnblogs.com/fnng/archive/2012/02/10/2345187.html

  

 

webdriver的對於不一樣瀏覽器經過不一樣的接口實現;下面介紹這幾種實現方式:

 

HtmlUnit的驅動程序 


 

這是目前最快,最輕量級的實施webdriver測試。正如它的名字所暗示的,這是基於HtmlUnit的。HtmlUnit是一個java實現基於web瀏覽器,沒有圖形用戶界面。對於任何語言綁定(Java之外)Selenium服務器須要使用此驅動程序。

 

用法

 

driver = webdriver.Remote("http://localhost:4444/wd/hub", webdriver.DesiredCapabilities.HTMLUNIT))

 

優勢

 

· 在Webdriver執行自動化最快的方式

 

· 一個純Java的解決方案,所以它是獨立於平臺的。

 

· 支持JavaScript的

 

缺點

 

· 模擬其餘瀏覽器的JavaScript行爲(見下文)

 

 

 

 

 

HtmlUnit驅動器JavaScript 

 


 沒有流行的瀏覽器使用JavaScript引擎,使用HtmlUnit(Rhino)。

 

若是你使用HtmlUnit測試JavaScript ,相比其餘瀏覽 結果可能會不同。

  

當咱們說「JavaScript」,其實咱們說的是「JavaScript和DOM」。雖然DOM是由W3C定義的,每一個瀏覽器都有本身特色和差別,HtmlUnit 有一套完整的實現DOM的方案,能很好的支持JavaScript ,但有別與其餘瀏覽器,和W3C標準的主流瀏覽器的DOM的實現存在差別,儘管其模仿其有他瀏覽器的能力。

 

在webdriver ,咱們選擇使用HtmlUnit來測試Javascript ,不過這樣存在問題和風險,但有愈來愈多的網站依賴於JavaScript ,咱們採起了保守的作法,HtmlUnit默認狀況下禁用JavaScript 。在webdriver的HtmlUnit的每一個版本,咱們從新評估這一決定:咱們但願在一些點上HtmlUnit的默認狀況下啓用JavaScript。

 

 

 

 

 

啓用JavaScript 

 


 啓用JavaScript的支持是很容易的:

 

 
driver = webdriver.Remote("http://localhost:4444/wd/hub", webdriver.DesiredCapabilities.HTMLUNITWITHJS)

這將致使HtmlUnit的驅動程序默認狀況下,模擬火狐3.6的JavaScript進行處理。

 

 

 

 

 

Firefox Driver

 


用Firefox的插件來控制火狐瀏覽器,firefox 配置文件使用selenium.xpi(插件)。默認狀況下,須要修改一些設置(see the source to see which ones),火狐驅動是可以運行在Windows,Mac,Linux上進行測試。目前在版本3.6,10(這個版本早過期了)

 

用法

 

driver = webdriver.Firefox()

 

優勢

 

· 在一個真正的瀏覽器上運行,並支持JavaScript的

 

· 速度比Internet Explorer的驅動程序

 

缺點

 

· 比HtmlUnit的驅動程序

 

修改火狐簡介

 

假設你想要修改的用戶代理字符串(如上述),但你已經有了一個欺騙Firefox的配置文件,它包含許多有用的擴展。有兩種方式得到此配置文件。假設使用Firefox的配置文件管理器(火狐 ProfileManager),已建立配置:

 

另外,若是配置文件還沒有在Firefox註冊:

 

當咱們正在開發firefox 啓動的特性,咱們可以正常使用。

 

正如咱們在Firefox Driver,開發功能,咱們可以使用。例如,直到咱們感受本機事件爲Linux上的Firefox是穩定的,他們是默認狀況下禁用。要啓用它們:

 

profile = webdriver.FirefoxProfile()

profile.native_events_enabled = True

driver = webdriver.Firefox(profile)

 

 

 

Internet Explorer Driver

 


 

該驅動程序控制.dll,於是只適用於Windows操做系統。每一個selenium釋放它的核心功能在xp下測試IE版本6,7和8,在Windows7下測試IE 9。

 

用法

 

driver = webdriver.Ie()

 

 

優勢

 

· 運行在一個真正的瀏覽器支持JavaScript與最終用戶看到的全部的行爲一致

 

缺點

 

· 顯然,Internet Explorer Driver只能在Windows上工做!

 

· 相對緩慢(儘管仍然是至關快速的)

 

· 自己不支持XPath的大多數版本。自動注入,這是明顯慢於其餘瀏覽器和進行比較時,在同一瀏覽器的CSS選擇器變慢。

 

· 自己不支持CSS版本6和7。

 

· CSS選擇器在IE 8和9是本地的,但這些瀏覽器不徹底支持CSS3

 

信息

 

維基頁面的最早進的最新信息,請參閱Internet Explorer的部分。請特別注意所需的配置部分。

 

 

 

Chrome驅動

 


 Chrome驅動程序維護/支持Chrome 項目自己。webdriver的工做與Chrome經過的chromedriver二進制(Chrome項目的下載頁面上找到)。你須要有兩個chromedriver和安裝一個版本的Chrome瀏覽器。爲了webdriver的自動找到,chromedriver須要要放在系統的路徑上。Chrome瀏覽器自己由chromedriver在默認安裝路徑找到。這些均可以經過環境變量覆蓋。 有關更多信息,請參閱維基

 

用法

 

driver = webdriver.Chrome()

 

優勢

 

· 在一個真正的瀏覽器上運行,並支持JavaScript的

 

· 由於Chrome是基於Webkit的瀏覽器,Chrome Driver會容許您驗證您的網站在Safari的測試效果。須要注意的是,由於瀏覽器使用其本身的V8 JavaScript引擎,而不是Safari瀏覽器的Nitro引擎,JavaScript的執行可能會有所不一樣。

 

缺點

 

· 比HtmlUnit的驅動程序

 

· 

 

 

獲取與Chrome驅動程序運行

 

鉻驅動程序可執行文件下載 ,並按照其餘的wiki頁面上的說明

 

Opera Driver

 

歌劇院驅動器在上使用Opera驅動程序的信息的selenium維基wiki文章

 

iPhone Driver

 

查看iPhone的驅動selenium維基上使用Mac的iOS驅動程序的信息,wiki文章

 

Android Driver

 

查看Android的驅動程序 硒selenium維基採用了Android驅動程序的信息,wiki文章

 

 

 

 

 

混合使用webdriver和RC技術

 


 

Webdriver替換selenium RC 

 

webdriver的Java版本的selenium RC API提供了一種實現。這意味着,你可使用Selenium-RC API和使用底層webdriver的技術。這主要是用於向後兼容。它容許那些使用selenium RC API的用戶使用webdriver覆蓋現有的測試套件。它提供幫助緩解遷移到selenium webdriver。此外,容許一我的使用這兩個API,在相同的測試代碼。

 

Selenium webdriver的使用是這樣的:

 

優勢

 

· webdriver的和selenium的API容許並排存在

 

· webdriver的遷移管理機制提供了一個簡單的Selenium RC API

 

· 不須要獨立的Selenium RC服務器的運行

 

缺點

 

· 不能支持每個方法

 

· 更多先進的selenium使用(using 「browserbot」 or other built-in JavaScript methods from Selenium Core)可能沒法正常工做

 

· 因爲底層實現差別,有些方法可能會比較慢

 

備份webdriver與selenium

 

webdriver的儘量多兼容selenium RC對瀏覽器的支持,同時仍然提供支持使用webdriver的API,因此爲了您能夠利用SeleneseCommandExecutor

 

Safari是支持這種方式,用下面的代碼(確保禁用彈出窗口攔截功能):

 

這種方法目前有一些主要限制,尤爲是findElements並不如預期般運做。此外,繁重的驅動瀏覽器,由於咱們使用的是selenium 的核心,你的JavaScript沙箱限制。

 

 

運行獨立Selenium服務器使用RemoteDrivers 

 

從selenium 的下載頁下載服務器獨立<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(or twice as many ports as the number of concurrent instances you plan to run)。在Windows下,你可能須要以及疏通各類應用。

相關文章
相關標籤/搜索