2012-05-11 67 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になり、ファイルをアップロードすることを決定することができた使用しています、Iアドインするの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でエラーメッセージが表示され、結果だけを探してみました(Googleの検索結果になるだろう、ここでこれを置く:

私が原因このエラーを取得し、これを変更しなければなりませんでした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-上の2つのパラメータを設定する必要が判明> ADDFILE()方法。変更を反映するために上記のコードを編集しました。

+0

ありがとうございます。これは大変です。 @J-RANのJSON Wire Protocolページ(Command + Fには何も得られていません)の –

+0

は、JSONWireProtocolの正式な機能ではありません。このソリューションは、公式の言語バインディングとは逆の処理をしています。それはあまりにも悪いですね。 – David

+0

このコードは、PHPバインディングに正式にパッチ/マージするために使用できます。この問題はプロジェクトページに35あります。私が周りを回るときに私は合併するでしょう。 – David

関連する問題