跳到主要內容

Robot Framework Keyword: wget - 下載網頁上的資料

Problem

網站大都有提供下載功能,驗證下載功能與內容是否正常是必要的測試項目之一。然而,SeleniumLibrary並沒有提供類似的keyword。本篇文章分享我們解決這個問題的歷程。

How to?

方法1: 透過外部程式wget

起初我們透過外部程式去達到測試需求。要達成此目的,有幾個步驟:

  1. 測試環境可以執行wget。
  2. 取得下載位置的連結。
  3. 設定Cookie。
  4. 執行下載。
  5. 驗證內容。

步驟1: 測試環境可以執行wget

大部分linux安裝起來就有wget,如果沒有就自行安裝;而windows可以從這裡下載執行檔,將它放到你的測試環境中。

步驟2: 取得下載位置的連結

在這裡我使用的是Get Element Attribute去取得hyper link的內容:

Get Element Attribute | //a[@id='link_id']@href

步驟3: 設定Cookie

假如你的網站是需要登入才能夠操作,這部分就是必要的。首先可以透過SeleniumLibrary提供的Get Cookies來取得當前session內容;它所拿到的內容是使用name1=value1; name2=value2;形式組成,只要挑你需要的屬性出來即可。對我們而言,JSESSIONID記載我們的登入資訊。

接著是要組成wget所需要的cookie file格式,詳細格式可以參考此連結,大致上如下:

${domain_ip}   FALSE   ${path}   FALSE   9999999999   JSESSIONID   ${jsession_id}

假如你是使用localhost連線,${domain_ip}就是localhost,否則就是要連線的機器IP。

步驟4: 執行下載

假如參數連結位置為${fileUrl}而下載檔案路徑${fileName},wget的執行指令如下:

${wget} --cookies=on --load-cookies ${cookie_file} --output-document ${fileName} ${fileUrl}

如果下載的位置為https,為了略過Certificate驗證,會搭配–no-check-certificate參數:

${wget} --cookies=on --no-check-certificate --load-cookies ${cookie_file} --output-document ${fileName} ${fileUrl}

步驟5: 驗證內容

這部分就是看各位的業務需求去做assertion。我的Keyword提供給大家參考:

Download File Wit Wget
    [Arguments]    ${fileUrl}    ${fileName}
    Log    ${fileUrl}
    ${cookies}    Get Cookies
    @{jessonid}    Split String    ${cookies}    JSESSIONID=
    ${location}    Get Location IP
    ${cookies}    Set Variable    ${location}\tFALSE\t//\tFALSE\t0\tJSESSIONID\t@{jessonid}[1]\r\n localhost\tFALSE\t//\tFALSE\t0\tJSESSIONID\t@{jessonid}[1]
    Log    ${cookies}
    Create File    ./cookies    ${cookies}
    ${currentdir}    Get Suite Directory
    ${isLinux}    Is Linux
    ${wget}    Set Variable If    '${isLinux}'!='TRUE'    ${currentdir}${/}..${/}commonResource${/}wget${/}wget    '${isLinux}'!='FALSE'    wget
    @{output}    Run And Return Rc And Output    ${wget} --cookies=on --no-check-certificate --load-cookies cookies --output-document ${fileName} \ ${fileUrl}
    Should Be Equal As Integers    @{output}[0]    0    @{output}[1]

方法2: 透過HttpClient Library

由於我們將預設連線修改為https,並且只允許TLS1.2,這導致在舊版本的Linux如RHEL6.0上無法透過預設的wget進行測試。因此改為自己實作TestLibrary去提供wget的功能。我所使用的HttpClient版本為httpclient-4.3.5,我直接將程式分享給各位,這可能會根據你的需求或library版本需要做些微調:

Robot Keyword:

Download File
    [Arguments]    ${fileUrl}    ${fileName}
    Log    ${fileUrl}
    ${cookies}    Get Cookies
    @{jessonid}    Split String    ${cookies}    JSESSIONID=
    ${location}    Get Location IP
    ${ret}    wget    ${fileUrl}    ${fileName}    JSESSIONID=@{jessonid}[1]    ${location}
    log    ${ret}

Test Library WgetLibrary:

import java.io.File;
import java.io.FileOutputStream;
 
import javax.net.ssl.SSLContext;
 
import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.cookie.BasicClientCookie;
 
public class WgetLibrary {	
	 public static final String ROBOT_LIBRARY_SCOPE = "TEST CASE";
	 public static final String ROBOT_LIBRARY_VERSION = "1.0.0";
 
	private BasicCookieStore createCookieStore(String cookies, String domain, String path){
		if( cookies == null || cookies.isEmpty() )
			return null;
 
		BasicCookieStore cookieStore = new BasicCookieStore();
		String[] cookiePairs = cookies.split(";");
		for( String cookiePair : cookiePairs){
			String[] cookieToken = cookiePair.split("=");
			BasicClientCookie cookie = new BasicClientCookie(cookieToken[0], cookieToken[1]);
			cookie.setDomain(domain);
			cookie.setPath(path);
			cookieStore.addCookie(cookie);
		}
		return cookieStore;
	}
 
	public long wget(String url, String destFile, String cookies, String domain){
		return wget(url, destFile, cookies, domain, "/");
	}
 
	public long wget(String url, String destFile, String cookies, String domain, String path){
		CloseableHttpClient httpClient = null;
		FileOutputStream fos = null;
		CloseableHttpResponse response = null;
		try {
			HttpClientBuilder builder = HttpClientBuilder.create();
 
			SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
			SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
			builder.setSSLSocketFactory(sslSocketFactory);
 
			BasicCookieStore cookieStore = createCookieStore(cookies, domain, path);
			if( cookieStore != null ) {
				builder.setDefaultCookieStore(cookieStore);
			}
 
			httpClient = builder.build();
			response = httpClient.execute(new HttpGet(url));
			fos = new FileOutputStream(new File(destFile));
			IOUtils.copy(response.getEntity().getContent(), fos);
			return response.getStatusLine().getStatusCode();
		} catch( Exception e ){
			throw new RuntimeException(e);
		} finally {
			Cleaner.close(fos);
			Cleaner.close(response);
			Cleaner.close(httpClient);
		}
	}
}

Reference

留言

這個網誌中的熱門文章

PostgreSQL - Unattended installation on windows

Introduction 要將別人軟體包裝到自己軟體中,不可或缺的東西就是Unattended installation。以Unattended installation來說,我們可以選擇透過Installer的silent mode安裝,也可以透過把目標軟體做成portable的版本。本篇文章分享這兩種方法,教導大家如何將PostgreSQL透過Unattended installation方式安裝到目標系統成為service。 Note. 本篇以PostgreSQL 10.7為例。 Install with installer Tips 安裝程式或反安裝程式的參數,除了可以直接上官網搜尋Installation User Guide以外,也可以直接使用help參數查詢: postgresql- 10.7 - 2 -windows-x64.exe --help Windows安裝程式主要有EnterpriseDB與BigSQL兩種。BigSQL版本安裝元件是透過網路下載且支援參數不如EnterpriseDB版本多,以我們需求來說,我們傾向於使用EnterpriseDB版本。接下來分享給大家安裝與反安裝方法。 Installation @ echo off set INSTALL_DIR =C:\postgres10 set INSTALLER =postgresql- 10.7 - 2 -windows-x64.exe   rem options for installation set SSMDB_SERVICE =postgresql- 10 set MODE =--unattendedmodeui none --mode unattended   set DB_PASSWD =--superpassword postgres set DB_PORT =--serverport 5432   set SERVICE_NAME =--servicename % SSMDB_SERVICE %   set PREFIX =--prefix "%INSTALL_DIR%" set DATA_DIR =--datadir "%INSTALL_DIR%\data"   set OPTIONS =

How to install RIDE on Windows?

Introduction 多年沒在Windows上開發RobotFramework,趁著這次整理一下RIDE安裝方法。 目前RIDE最新版本與Python對應版本如下: (3.6 < python <= 3.11) Install current released version (2.0.8.1) with: pip install -U robotframework-ride 安裝Python 直接到Python官網找尋最新的3.11版本,我使用3.11.9: link 。安裝就是一直下一步而已。 安裝wxPython 每次安裝RIDE最困難的都是wxPython。看了一下 官網 描述,我就姑且相信一下: 接著進入下 載頁面 就有安裝教學。基本上就是到Python目錄下的Scripts直接執行以下command: pip install -U wxPython 安裝RIDE 接著就如RIDE官網所說,執行以下command: pip install -U robotframework-ride 啟動RIDE 直接在相同目錄下執行ride就可以啟動了,你也可以直接在桌面建ride連結,加快下次啟動時間。 沒想到這次這麼順利就安裝完成了。因為我是使用java去啟動robot framework,就不特別講要怎麼使用pip安裝robot framework了。

Hello World!

即將要搬家,因此舊網頁內容將慢慢轉移至Blogger。 如果要存取舊網頁,可以使用以下連結: https://wiki.tonylin.idv.tw/dokuwiki/doku.php