跳到主要內容

發表文章

目前顯示的是有「Selenium」標籤的文章

升級SeleniumLibrary到4.5.0與Selenium到3.141.0

最近我們將RobotFramework升級至4.1.2,因為Jython的關係這個是目前可以使用Java執行的最後版本。 我們目前Selenium相關的Libraries版本如下: Selenium2Library - 3.0.0 (Latest, https://github.com/robotframework/Selenium2Library ) SeleniumLibrary - 3.0.0 ( https://github.com/robotframework/SeleniumLibrary/releases ) Selenium - 3.8.0 其中Selenium2Library已經沒在維護,也是最後一個版本,它所做的事情僅僅是把keyword forward給SeleniumLibrary。所以升級重點在SeleniumLibrary與Selenium。 而要升級這些Libraries,最重要的就是要知道它們彼此之間的相依,還有python版本的支援度。在我查詢套件的release note之後,因為4.1.2版本的jython只能支援到python 2.7.x,所以能升級的版本就有限制。其中SeleniumLibrary的情況如下: SeleniumLibrary 5.0.0 - 不支援Python 2 and Jython  SeleniumLibrary 4.5.0 - Python 2.7 and Selenium 3.141.0+  SeleniumLibrary 3.3.1 - Python 2.7 and Selenium 3.4+ 所以搭配了Selenium後,以下為我的第一個升級計畫: Selenium - 3.141.0 SeleniumLibrary - 3.3.。主要想確定是否會有deprecated items產生。 升級方式就是把以上原始碼丟到Lib底下,執行robot測試的時候會透過jython重新編譯。在我執行後,出現了urllib3找不到的問題: 我想可能是原本的套件中有包含urllib3,因此我到urllib3的package網站查了release note,找了可以匹配python 2.7的版本: urllib3 - 1.26.20 (https://pypi.org/project/...

解決RobotFramework從3.1.2升級到3.2.2之後,Choose File突然會整個Hand住的問題

考慮到自動測試環境的維護,我們很久以前就使用java去執行robot framework。前陣子開始處理從3.1.2升級到3.2.2的事情,主要先把明確的runtime語法錯誤與deprecate item處理好,這部分內容可以參考: link 。 直到最近才發現,透過SeleniumLibrary執行Choose File去上傳檔案的動作,會導致測試案例timeout。本篇文章主要分享心路歷程與解決方法,我也送了一條issue給robot framework: link 。 我的環境如下: RobotFramework: 3.2.2 Selenium: 3.141.0 SeleniumLibrary: 3.3.1 Remote Selenium Version: selenium-server-standalone-3.141.59 首先並非所有Choose File的動作都會hang住,有些測試案例是可以執行的,但是上傳一個作業系統ISO檔案一定會發生問題。後來我透過wireshark去比對新舊版本的上傳動作,因為我使用 Remote Selenium ,所以Selenium會先把檔案透過REST API發送到Remote Selenium Server上。從下圖我們可以發現,在3.2.2的最後一個TCP封包,比3.1.2大概少了500個bytes。 於是就開始了我trace code之路。包含SeleniumLibrary產生要送給Remote Selenium Server的request內容,還有HTTP Content-Length的計算,我都確認過沒有問題。 最後發現問題是出在socket API的使用上,就是下圖的這支code: 最後發現可能因為開始使用nio的方式送資料,但沒處理到尚未送完的資料內容,而導致發生問題。加一個loop去做計算就可以解決了。 最後我有把解法提供給robot framework官方,在他們出新的版本之前,我是將改完的_socket.py放在我們自己的Lib底下,好讓我們測試可以正常進行。(shutil.py應該也是為了解某個bug而產生的樣子..)

Jython+Selenium2Library無法在Windows上啟動Firefox

Problem 這陣子開始著手於升級Selenium2,我們的環境是透過Java啟動RobotFramework(2.9),在Runtime時去編譯Selenium與Selenium2Library。這樣的模式在Linux上,可以正常的跑完測試用的測試案例;然而在Windows上卻會出現如下圖錯誤: How to? 首先會發現firefox並沒被啟動,然後有OSError: Operation not permitted。後來花了一些時間trace了Selenium的程式碼,發現錯誤是在複製firefox profile到暫存資料夾產生的: # firefox_profile.py的__init__ shutil . copytree ( self . profile_dir , newprof , ignore = shutil . ignore_patterns ( "parent.lock" , "lock" , ".parentlock" ) ) 雖然檔案都有被複製完成,但就是會發生錯誤;雖然嘗試將例外catch起來吃掉,但不只這地方會發生問題。於是我就開始找尋原因。我將robotframework.jar中Lib/shutil.py.class刪除,並將shutil.py複製到Lib資料夾下: 後來發現問題是在copystat>copystat做hasattr(os, 'chflags')的動作。原本程式碼中,有針對Windows發生例外(WindowsError)時,會做pass的動作: try : copystat ( src , dst ) except OSError , why: if WindowsError is not None and isinstance ( why , WindowsError ) : # Copying file access times may fail on Windows pass else : errors. append ( ( ...

Robot Framework - How to assert multiple text node?

Problem 傳統的網頁資料更新,都是透過刷新整頁方式;隨著javascript的普及化,進步到針對dom node刷新。而資料型態如果為遞增的方式,像jenkins build info或是動作執行過程,很可能為了效能不針對整個node刷新,而採用append的方式。透過瀏覽器所提供的Element檢測器,會看到如下圖情況: 一個pre code底下包含了三個text node,當在Selenium IDE與Chrome Developer Tools中使用以下xpath,由於是找到第一個,所以無法找到任何批配的節點: 本篇文章主要告訴你,如果某個節點資料是動態插入的,該如何透過selenium去做assertion。 How to? 以我的測試網頁為例子,要能搜尋到text包含g2的字串,可用以下兩個xpath: 透過index指定位置: //pre[contains(text()[2],'g2')] 先列出所有text()項目再給予條件: //pre[text()[contains(.,'g2')]] 但在動態生成的網頁中,很難直接指定index去做assertion。綜合這兩個做法,並試驗一些可能可用的keyword,如下: 除了第二個是我們原先問題會錯之外,其餘的都能正常找到指定項目。所以目前有兩個解法: text()優先的xpath。 使用Wait Until Element Contain與Element Should Contain: 通常適用於node有好辨別的特徵,如id。 測試網頁 <!DOCTYPE html> < html > < head > < script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js" >< / script > < script > $(document).ready(function(){ $("#gg").append('g1'); $("#gg").append('g2'); $("#gg...

Robot Framework - No active session with ID problem

Problem 這陣子將SeleniumLibrary升級至3.0.0,且selenium node中的server升級至3.8.1、firefox使用Mozilla GeckoDriver 0.19.0。沒想到當天晚上跑完自動測試後,出現了大量錯誤,其中一個就是No active session with ID: 在發生問題後,如果執行除了Open Browser以外的動作,如Set Selenium Timeout、Capture Page Screenshot或Close All Browsers,就會出現如上述訊息,而selenium node上的機器會有大量的瀏覽器開啟且沒有關閉。 本篇文章主要分享我發現的原因與避掉方式。 How to? 經過trace,在我們的測試中,必須經過一定步驟才會發生問題。以下是我簡化模擬出來的情況: 在testcase 1中close window後,目標機器瀏覽器會被關閉,這也導致close all browser會出問題;而在testcase 2雖然重新啟動了一個新的瀏覽器,但selenium卻無法獲得新的session id。 因此,最後將重複關閉(Close Window)的行為給拿掉就可以“避掉”問題了。

StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

Problem 這陣子把SeleniumLibrary更新到了3.0後,開始發生測試不穩定的問題;其中一樣就是在呼叫Get Text時,發生StaleElementReferenceException: Message: stale element reference: element is not attached to the page document的問題。 How to resolve? 參考網路上資料,大都說是由於要存取的目標沒出現在網頁上;然而在我們測試報表中,Screenshot是看的到我們所要操作的目標。因此我們推測可能是由於websocket引起的refresh所造成的。面對這個問題,我們採取retry的做法: Get Text [ Arguments ] ${locator} ${text} Wait Until Keyword Succeeds 2x 10ms Selenium2Library.Get Text ${locator} [ Return ] ${text} 透過Wrapper的方式,把SeleniumLibrary的GetTex包在WrapperLibrary內去達到retry的效果。 與其說真的解決,不如說這是個workaround。 Reference stale element reference: element is not attached to the page document Stale Element Reference Exception

Robot Framework - SSL Certificate Error On IE11

Problem 這陣子我們將web連線預設由原本的http轉到https,然而在透過IE做驗收測試時,出現了Certificate Error而導致測試無法繼續下去: 本篇是分享我實驗過與可能的解決方法。 How to resolve? 我們使用selenium grid的方式做測試,selenium的node搭載環境如下: OS: Windows2012 R2 x64 IE: IE 11.0.9600.18618 selenium-server-standalone: 3.8.1 IEDriverServer: 3.4.0.0 (32.bit) 接下來分享我實驗的方法: 使用desired_capabilities 我在Open Browser的keyword之後加入以下參數: desired_capabilities=acceptSslCerts:true;trustAllSSLCerficates:true 透過grid node的console可以看到參數有傳過去,但無法解決問題。 更新IEDriverServer 我將版本更新到3.8.0.0,但Open Browser會有錯誤訊息;礙於時間關係,就不繼續追蹤下去。 調整IE11設定 起初我調整Internet Options > Advanced設定,但沒作用: 接著我改使用匯入Certificate的方式,點擊Certificate error > View Certificates > Install Certificate: 按照安裝步驟點下去,唯一要注意的是,憑證放置位置要選Trusted Root Certification Authorities: 完成之後重新啟動IE還是會看到Certificate Error,但錯誤已經變成Address Mismatch,這是由於簽發的名稱與實際連線主機名稱不同: 所以要去改IE設定,取消這個檢查: 重新啟動IE後應該就能夠正常執行測試。 這個方法只適用於專門測試的機器,一般正常使用的機器這樣做會降低安全性;此外,如果憑證有改或新增就要再執行匯入,比較不方便。 Reference Selenium Grid cannot launch IE11 and report IE driver cannot bypass insecure SS...

Robot Framework - Choose File在Remote Selenium上的問題

如果透過Remote Selenium Server去執行測試,在跑Robot上的測試資料該如何讓遠端機器取得呢? 經過爬文發現,Selenium2Library的Choose File已解決這問題; 目前Windows上常常有卡住的問題,即使設定timeout也無法解決: related issue 這個issue中有人使用2.4x版本,我們是使用2.48 根據IE driver changelog 內容,3.3版本後應該要有解。

Robot Framework - Element is not clickable issue on chrome

Problem 這陣子將SeleniumLibrary升級至3.0之後,在Firefox上測試遇到難以解決的問題,也因此將測試瀏覽器改為Chrome;然而移到chrome之後,原先可以在firefox上執行的測試,反而變得無法執行。其中一樣就是出現Element is not clickable的問題。 How to resolve? 我要點擊的位置是Refresh的button: 而我一開始使用的xpath是 //span[text()='Refresh'] 但卻出現了以下錯誤訊息: WebDriverException: Message: unknown error: Element < span class = "ui-button-text" > ... < / span > is not clickable at point (805, 96). Other element would receive the click: < span class = "ui-button-icon-primary ui-icon ui-icon-refresh" >< / span > (Session info: chrome=63.0.3239.132) (Driver info: chromedriver=2.34.522940 (1a76f96f66e3ca7b8e57d503b4dd3bccfba87af1),platform=Windows NT 6.3.9600 x86_64) ChromeDriver使用模擬方式去點element中間的位置;假如你所給予的位置是使用者點不到的位置,就有可能會發生這樣的問題。 舉例來說,使用一個modal dialog會讓背景呈現蓋住的效果;對使用者來說,背景是無法點擊的。假如這時候透過ChromeDriver去點擊背景的element,就會發生無法點擊的問題。 以我的問題來說,將xpath改為圖片或button的xpath即可解決。 因此,Click Element的xpath最好是設定為使用者一定可以點擊的到的位置。 Reference Chrome - Element is not clickabl...

Robot Framework: 如何控制div上的scrollbar?

Problem 在使用grid呈現大量資料時,很有可能會發生畫面的長度無法呈現出所有內容;因此在div的style中,會搭配overflow: auto讓長度不足時顯示出scrollbar,如下: 而我在使用Get Text去取得如畫面較右方(index大概第10個)的內容時,都會找不到對應的element;使用Get Source或Get Element Count也都拿不到如預期的資料與數量。經過測試,發現只要將scrollbar往右移就可以解決我們的問題。本篇文章要分享給大家控制div scrollbar的方法。 How to resolve? 我們主要的解決方式是透過Execute Javascript去控制div中的scrollbar,會使用到DOM element的兩個屬性: Element.scrollLeft: 控制橫向scrollbar位置。 Element.scrollTop: 控制垂直scrollbar位置。 假設我們要針對class為viewport element的橫向scrollbar做操作,會這樣寫: Execute Javascript | document.getElementByClassName ( 'viewport' ) [ 1 ] .scrollLeft = 500 如果要對id為grid的垂直scrollbar做操作,會這樣寫: Execute Javascript | document.getElementById ( 'grid' ) .scrollTop = 500 在寫之前,可以先嘗試使用瀏覽器的debug console實驗一下。 Reference selenium之 如何控制网页内嵌div中滚动条的滚动 Element.scrollLeft

WebDriverException: Message: Java heap space

Problem 大部份的軟體在某些情況,肯定會限制使用者所上傳的檔案大小。我們有一個測試想要上傳64M大小的檔案,確出現以下錯誤: How to resolve? 由於我們使用selenium grid方式管理與執行測試,我推測這應該與selenium node的jvm有關。原先我的腳本如下: @ echo off set BASE = % ~dp0 set JAVA_PATH = % BASE % jre\bin\java.exe set PATH = % PATH % ; % BASE % ; set HUB_IP =192.168.0.200   cd / d "%BASE%" "%JAVA_PATH%" -jar selenium-server-standalone-3.141.59.jar -role node -hub http: //% HUB_IP % : 4444 / grid / register -port 5555 我特別設定heap大小後,就能夠解決這個問題: "%JAVA_PATH%" -Xmx1024m -Xss1152k -jar selenium-server-standalone-3.141.59.jar -role node -hub http: //% HUB_IP % : 4444 / grid / register -port 5555

Robot Framework - Execute Java Script

Fix Issues 如何控制div上的scrollbar? Scripts Ctrl + A 65為A的key code: ${"body"} .trigger ( { type: 'keydown, which: 65, ctrlKey: true' } ) ; Ctrl + 滑鼠左鍵 假設你要點擊的element包含test_target字串: $ ( ":contains('test_target')" ) .trigger ( { type: 'click' , which: 1 , ctrlKey: true } ) ; 1是左鍵,3是右鍵。 Ctrl + 滑鼠左鍵 - JQuery的Selectable 由於 Selectable 的實作有根據座標位置,單純透過click是無法選到你要的東西,必須使用clickAt。如果要使用trigger,可以使用mousedown+mouseup搭配座標: $ ( ":contains('test_target')" ) .trigger ( { type: 'mousedown' , which: 1 , ctrlKey: true , pageX: 1 , pageY: 1 } ) ; $ ( ":contains('test_target')" ) .trigger ( { type: 'mouseup' , which: 1 , ctrlKey: true , pageX: 1 , pageY: 1 } ) ; (以上是根據JQuery的Source code研究出來的做法)

Robot Framework Keyword: Wait Something Keywords

測試一個Web應用程式免不了Redirect的動作。當我們從頁面A到頁面B要做某些測試時,可能因為電腦或網路剛好很慢,造成待測項目沒有及時出來而fail。這種情況並不一定是個bug! 除此之外 還有以下是會用到wait keyword的情況: 點擊Element後,等它回應驗證結果。如Alert視窗,或是經過操作後,希望某個Element出現或消失。 導向後要確認此頁面是否為你要的頁面。 確認系統中Service狀態。 在robot的best practice中,也提及用wait until取代sleep較好,可以減少不必要的浪費。皆下來看看常見的需求該如何透過wait until實作。 Wait Until Page Not Contains Element RobotFramework中並沒有提供Wait Until Page Not Contains Element的keyword,但這卻是必用的keyword。舉例來說,Dialog會有OK與Cancel,在我們點擊OK或Cancel後,沒甚麼問題的話Dialog就會消失。如果還有下一個動作要執行,我們必須等到這個Dialog消失才能做動作,此時就需要這個keyowrd。而這個Keyword的實作,有兩種方法: For loop + Page Should Not Contain Element。 Wait Until Keyword Succeeds + Page Should Not Contain Element。 怎麼看都是方法2比較優雅且簡單。可以這樣寫這個keyword: # Keyword Name: Wait Until Page Not Contains Element # Arguments: ${locator} | ${timeout} | ${retry_time} Wait Until Keyword Succeeds | ${timeout} | ${retry_time} | Page Should Not Contain Element | ${locator} | ${EMPTY} | NONE 用${timeout}來設定timeout的時間,${retry_time}為多久執行一次 Page Should Not Contain Eleme...

SeleniumLibrary - Open Browser

某測試機器裝了兩個firefox,但SeleniumLibrary不支援較新版本的firefox,因此想用舊的跑。翻了一下library document,裡面有提到: a string like *custom /path/to/browser-executable can be used to specify the browser directly 我也傻傻的使用 Open Browser | http://localhost:8080 | *custom /opt/firefox/firefox 正確應該是這樣 Open Browser | http://localhost:8080 | *firefox /opt/firefox/firefox

Migrate SeleniumLibrary to Selenium2Library

Introduction 分享從SeleniumLibrary(SL1)升級到Selenium2Library(SL2)的歷程與方法。 Note. 某一天看到Selenium2Library從3.0開始後,已經於自身library中提供wrapper的實作,要升級的人可以嘗試看看。 link Browser 由於SL1與SL2支援的瀏覽器版本有差異存在,有考慮過使用portable的firefox,但發現難以支援所有需要的作業系統。因此最無痛的方式,就是透過Remote Selenium,可參考 此篇教學 。 Implement A Wrapper Library SL1與SL2 Keyword有不少差異存在。而升級到SL2的過程,並非一蹴可幾。因此我透過一個SeleniumLibraryWrapper,讓Keyword的呼叫使用共同的介面,而要使用SL1或SL2則由各別Keyword決定。方法如下: Import Selenium Library: 偵測要使用的Selenium版本,並設定為Global Variable。 Keyword Wrapper: 透過判斷版本的結果,去決定要使用SL1或SL2的Keyword。 Import Selenium Library 由於SL1不相容於2.9以上版本的RobotFramework,而SL2必須用2.9以上版本。因此我們可以透過判斷2.9版本以上才支援的keyword是否存在,來確認Selenium環境,接著再匯入各別版本的SeleniumLibrary。 Keyword Wrapper 我以Click Element為例。Click Element在SL1中,接收${locator}、${dont_wait}與${coordinates}三個參數,而SL2只接受${locator}。如果要將SL1轉到SL2,針對${dont_wait}可選擇略過;${coordinates}則要改用Click Element At Coordinates。由於我沒用到${coordinates},所以我僅以${dont_wait}做範例: 其它Keyword也是用類似的方法,至於要做到什麼程度,看你們的需求而定了。 Keyword Changes 這部分針對Keyword行為改變做說明,這是要補充官方沒列到的: 無法操作invi...

Robot Framework - Web Test HelloWorld

Introduction RobotFramework是一個Plugin架構的測試框架。以一個Web應用程式來說,可能有HTML、Flash或Applet等顯示方式。就我目前了解,對於HTML可以使用 SeleniumLibrary 去做測試;Flash在SeleniumLibrary2.6後,也支援了 FlexTesting ;之前問過Google大師,Applet據說可以用 SwingLibrary 做測試。我所撰寫測試的應用程式,大都使用Selenium即可;少部分有用到Applet的UI,則是透過與Sikuli整合來做操作。本篇文章將告訴你,要如何開始使用SeleniumLibrary測試Web Application。 Environment SeleniumLibrary是透過Selenium的jar檔,因此必須要有JRE。官方的安裝可以參考InstallationInstrutions。但依照我的角度我會建議妳使用portable的方式,製造與使用的方法可以參考我之前的教學: How to build portable robot-package? First TestCase 我將寫的,是會連至Google首頁並確認搜尋按鈕有出現的測試案例。一個Web的測試案例,基本需要做的事情包含匯入SeleniumLibrary、啟動SeleniumServer、連至測試網頁、做測試、最後是關閉網頁與SeleniumServer。此外,如果你的測試瀏覽器是fireofx,請先參考 這個網頁 去製作SeleniumProfile,這是決定你firefox啟動後的設定。 TestSuite 我習慣在Suite Setup時,啟動SeleniumServer、打開瀏覽器並導向測試應用程式的URL;在Suite Teardown則是關閉瀏覽器與停止SeleniumServer。除非是需要打開多個瀏覽器的案例,不然這個做法適用於大部分情況。來看看我TestSuite的宣告,Setup會呼叫Prepare To Start Selenium Server這個自己實做的Keyword,細節稍後說;Teardown則是呼叫SeleniumLibrary的Stop Selenium Server,會關閉瀏覽器與SeleniumServer。 Prepare To Start Se...