2012-05-11 62 views
6

我一直在搜索有關如何在PHP上使用Selenium WebDriver遠程上傳文件的StackOverflow(和其他資源)。我讀過這個http://saucelabs.com/blog/index.php/2012/03/selenium-tips-uploading-files-in-remote-webdriver/,它提到你需要使用「setFileDetector」方法來改變你使用的WebDriver庫的工作方式。使用PHP在Selenium WebDriver上遠程上傳文件

如果我使用的是Ruby或Java,這應該可以正常工作。另一方面,大多數PHP框架都沒有這種方法。

任何人都可以告訴我如何在PHP中做到這一點?具體來說,我使用的phpwebdriver庫http://code.google.com/p/php-webdriver-bindings/

回答

9

我能夠確定的是,JsonWireProtocol上傳的文件將通過與檢查出的SauceLabs.com博客文章(https://saucelabs.com/jobs/1a408cf60af0601f49052f66fa37812c/selenium-server.log)的原始日誌所以/session/<sessionId>/file,我創建此功能在增加,到PHP-webdriver的-綁定庫:

/** 
* Send a file to your Remote WebDriver server 
* This will return the local URL of the file you uploaded, which will then 
* let you use sendKeys in file input elements 
* @params String $value - a local or remote file to send 
* @return String $resopnseValue - the local directory where the file resides on the remote server 
*/ 
public function sendFile($value) { 
    $file = @file_get_contents($value); 

    if($file === false) { 
     return false; 
    } 

    $file = base64_encode($file); 
    $request = $this->requestURL . "/file"; 
    $session = $this->curlInit($request); 
    $args = array('file' => $file); 
    $postargs = json_encode($args); 
    $this->preparePOST($session, $postargs); 
    $response = trim(curl_exec($session)); 

    $responseValue = $this->extractValueFromJsonResponse($response); 
    return $responseValue; 
} 

一下添加到WebDriver.php文件。

使用,只需做這樣的事情:

... 
$file_location = $webdriver->sendFile('http://test.com/some/file.zip'); 
$file_input = $webdriver->findElementBy(LocatorStrategy::id, 'uploadfile'); 
$file_input->sendKeys(array($file_location)); 

我希望這將有助於其他開發人員,用了像3小時尋找這個問題的答案。

更新:

我有這個變化,由於收到此錯誤:

Expected there to be only 1 file. There were: 0 

希望把這個在這裏會得到谷歌的結果(我試圖尋找谷歌和錯誤消息的唯一結果它可以找到Google Code上對源代碼的引用)。

爲了解決這個問題,我能夠推斷出你發送的文件實際上需要壓縮。所以我增加了源代碼來使用PHP的ZipArchive庫。我會繼續在上面記錄保存的舊代碼,但請在這裏使用新代碼:

public function sendFile($value, $file_extension = '') 
{ 
    $zip = new ZipArchive(); 

    $filename_hash = sha1(time().$value); 

    $zip_filename = "{$filename_hash}_zip.zip"; 
    if($zip->open($zip_filename, ZIPARCHIVE::CREATE) === false) { 
     echo 'WebDriver sendFile $zip->open failed\n'; 
     return false; 
    } 

    $file_data = @file_get_contents($value); 
    if($file_data === false) { 
     throw new Exception('WebDriver sendFile file_get_contents failed'); 
    } 

    $filename = "{$filename_hash}.{$file_extension}"; 
    if(@file_put_contents($filename, $file_data) === false) { 
     throw new Exception('WebDriver sendFile file_put_contents failed'); 
    } 

    $zip->addFile($filename, "{$filename_hash}.{$file_extension}"); 
    $zip->close(); 

    $zip_file = @file_get_contents($zip_filename); 
    if($zip_file === false) { 
     throw new Exception('WebDriver sendFile file_get_contents for $zip_file failed'); 
    } 

    $file = base64_encode($zip_file); 

    $request = $this->requestURL . "/file"; 
    $session = $this->curlInit($request); 
    $args = array('file' => $file); 
    $postargs = json_encode($args); 
    $this->preparePOST($session, $postargs); 
    $response = trim(curl_exec($session)); 

    return $this->extractValueFromJsonResponse($response); 
} 

更新:原來,你需要設置在$ zip-兩個參數> addFile()方法。編輯上述代碼以反映更改。

+0

謝謝。這麼做太多了。它不在JSON Wire Protocol頁面上(Command + F至少沒有任何東西) –

+0

@ K-RAN,該功能並不是JSONWireProtocol的正式組成部分。該解決方案與官方語言綁定的做法相反。這太糟糕了,不是嗎? – David

+0

此代碼可用於正式補丁/合併到PHP綁定。項目頁面中存在問題35。當我接近它時,我會合並。 – David

相關問題