1. 程式人生 > >記錄我遇到的使用selenium讓人摸不著頭腦的問題

記錄我遇到的使用selenium讓人摸不著頭腦的問題

問題一 

使用webdriver驅動firefox瀏覽器時如果不設定引數,預設使用的Firefox的profile和平時開啟瀏覽器使用的firefox不一樣,如果要使用平常使用的配置,解決方法:


string sPath = @"C:\Users\xxxx\AppData\Roaming\Mozilla\Firefox\Profiles\5f3xae4a.default"; 
FirefoxProfile ffprofile = new FirefoxProfile(sPath);

sPath 是你的firefox瀏覽器的配置檔案路徑,如何獲得這個路徑,google一下你就知道。

btw,火狐瀏覽器的profile還可能引起

《selenium webdriver缺陷》中提到的獲取頁面元素的座標錯誤問題,如果click無反應應該獲取一下元素座標,看是否是因為這個原因。

問題二

我之前一篇文章《selenium webdriver缺陷》介紹過,當頁面上有js或者ajax等動態元素時,webdriver判斷頁面載入完成實際上只是html和js程式碼載入完成,js生成的元素是否已經出現在頁面原始碼中是未知的,所以必須顯示指明等待某元素出現,以判斷這個元素是否已經被js等動態指令碼生成:

wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
wait.Until(ExpectedConditions.ElementExists(by));

問題三

操作頁面元素時丟擲異常,頁面元素為不可見,無法操作。這個問題的原因我遇到二種,一種是css樣式直接指定該元素或者父元素的display屬性為none,解決方法, 使用js注入直接修改元素的display屬性為block,下面的程式碼是修改FindElements獲取的多個元素的display屬性。

ReadOnlyCollection<IWebElement> eles = driver.FindElements(by);
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
foreach (IWebElement ele in eles)
{
    js.ExecuteScript("arguments[0].style.display='block';", ele);
}

第二種原因是js的問題,因為還沒有輸出完畢,獲取到的元素有可能被提示為不可見,解決方法:

執行緒sleep一定的時間等待它為可見,或者用webdriver的判斷元素是否可見的方法,等待直到元素可見才執行之後的程式碼。(建議使用webdriver提供的方法)

問題四

操作元素時得到等待元素超時的異常。這個問題大多人第一反應可能是元素還沒出現在頁面原始碼中,例如問題二中提到的。但還有另外一個原因也會導致丟擲這個異常,這是我今天做youtube自動上傳模組遇到的情況。

其實webdriver對頁面元素的所有操作都是通過將js程式碼注入到目標頁面實現的(btw,為了實現這個目的webdriver使用了一個技巧避開了瀏覽器的”同源策略“,這也是webdriver的一個創造性的地方,有興趣可以google一下),那麼就存在js指令碼的執行順序問題,youtube上傳頁面需要執行js指令碼以把檔案上傳到伺服器,在整個檔案上傳的過程中,我程式碼中對頁面元素的操作都會丟擲超時異常,而且這個時候元素已經出現在頁面原始碼中了(我的程式中在操作元素之前獲取了當時的頁面原始碼,元素確實已經存在),所以不是因為元素不存在導致的超時,而是頁面上的上傳檔案的js原始碼執行阻塞了操作元素的webdriver的js原始碼的執行,直到超時報錯,另外,如果由於對元素的操作本身時間過長,比如sendkey()一大堆的文字,當超過設定的超時時限sendkey還沒執行完畢也會得到這個異常。解決方法:

因為不知道上傳檔案需要多久,所以如果元素的操作時機沒什麼限制的話,捕獲異常後繼續等待,直到操作成功為止。

如果是因為元素自身操作超時,那麼可以尋找不需要那麼長執行時間的替代方案,或者加長超時時間保證操作有充足的執行時間。

問題五

driver初始化異常。我遇到過兩種原因導致出現這個問題,一是firefox配置資料夾所在的硬碟分割槽空間不夠,二是程式執行時有以webdriver以外的方法開啟的firefox瀏覽器例項(比如雙擊firefox瀏覽器快捷方式開啟)。解決方法:

清理硬碟空間。先關閉導致問題產生的瀏覽器例項再執行程式。

問題六

元素click()之後,本該執行的操作順利執行,但是程式卻掛在click()方法中,直到丟擲連結遠端伺服器超時異常。

解決方法:在google code上很多老外都遇到這樣的問題,似乎是一個selenium的bug,目前沒有很好的解決方法,只能等到超時後捕獲這個異常,繼續下面的程式執行,為了縮短等待的時間,可以把這個超時時間設定得短一點:

driver = new FirefoxDriver(new FirefoxBinary(), ffprofile, new TimeSpan(0, 0, 0, 60)); 最後一個引數就是設定對應的超時時間,這個超時時間不是隱式、顯式等待以及scripttimeout,而且似乎也沒辦法在driver 初始化之後進行改動。